github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/internal/reflectlite/type.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 reflectlite implements lightweight version of reflect, not using 6 // any package except for "runtime" and "unsafe". 7 package reflectlite 8 9 import ( 10 "internal/unsafeheader" 11 "unsafe" 12 ) 13 14 // Type is the representation of a Go type. 15 // 16 // Not all methods apply to all kinds of types. Restrictions, 17 // if any, are noted in the documentation for each method. 18 // Use the Kind method to find out the kind of type before 19 // calling kind-specific methods. Calling a method 20 // inappropriate to the kind of type causes a run-time panic. 21 // 22 // Type values are comparable, such as with the == operator, 23 // so they can be used as map keys. 24 // Two Type values are equal if they represent identical types. 25 type Type interface { 26 // Methods applicable to all types. 27 28 // Name returns the type's name within its package for a defined type. 29 // For other (non-defined) types it returns the empty string. 30 Name() string 31 32 // PkgPath returns a defined type's package path, that is, the import path 33 // that uniquely identifies the package, such as "encoding/base64". 34 // If the type was predeclared (string, error) or not defined (*T, struct{}, 35 // []int, or A where A is an alias for a non-defined type), the package path 36 // will be the empty string. 37 PkgPath() string 38 39 // Size returns the number of bytes needed to store 40 // a value of the given type; it is analogous to unsafe.Sizeof. 41 Size() uintptr 42 43 // Kind returns the specific kind of this type. 44 Kind() Kind 45 46 // Implements reports whether the type implements the interface type u. 47 Implements(u Type) bool 48 49 // AssignableTo reports whether a value of the type is assignable to type u. 50 AssignableTo(u Type) bool 51 52 // Comparable reports whether values of this type are comparable. 53 Comparable() bool 54 55 // String returns a string representation of the type. 56 // The string representation may use shortened package names 57 // (e.g., base64 instead of "encoding/base64") and is not 58 // guaranteed to be unique among types. To test for type identity, 59 // compare the Types directly. 60 String() string 61 62 // Elem returns a type's element type. 63 // It panics if the type's Kind is not Ptr. 64 Elem() Type 65 66 common() *rtype 67 uncommon() *uncommonType 68 } 69 70 /* 71 * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go). 72 * A few are known to ../runtime/type.go to convey to debuggers. 73 * They are also known to ../runtime/type.go. 74 */ 75 76 // A Kind represents the specific kind of type that a Type represents. 77 // The zero Kind is not a valid kind. 78 type Kind uint 79 80 const ( 81 Invalid Kind = iota 82 Bool 83 Int 84 Int8 85 Int16 86 Int32 87 Int64 88 Uint 89 Uint8 90 Uint16 91 Uint32 92 Uint64 93 Uintptr 94 Float32 95 Float64 96 Complex64 97 Complex128 98 Array 99 Chan 100 Func 101 Interface 102 Map 103 Pointer 104 Slice 105 String 106 Struct 107 UnsafePointer 108 ) 109 110 const Ptr = Pointer 111 112 // tflag is used by an rtype to signal what extra type information is 113 // available in the memory directly following the rtype value. 114 // 115 // tflag values must be kept in sync with copies in: 116 // cmd/compile/internal/reflectdata/reflect.go 117 // cmd/link/internal/ld/decodesym.go 118 // runtime/type.go 119 type tflag uint8 120 121 const ( 122 // tflagUncommon means that there is a pointer, *uncommonType, 123 // just beyond the outer type structure. 124 // 125 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 126 // then t has uncommonType data and it can be accessed as: 127 // 128 // type tUncommon struct { 129 // structType 130 // u uncommonType 131 // } 132 // u := &(*tUncommon)(unsafe.Pointer(t)).u 133 tflagUncommon tflag = 1 << 0 134 135 // tflagExtraStar means the name in the str field has an 136 // extraneous '*' prefix. This is because for most types T in 137 // a program, the type *T also exists and reusing the str data 138 // saves binary size. 139 tflagExtraStar tflag = 1 << 1 140 141 // tflagNamed means the type has a name. 142 tflagNamed tflag = 1 << 2 143 144 // tflagRegularMemory means that equal and hash functions can treat 145 // this type as a single region of t.size bytes. 146 tflagRegularMemory tflag = 1 << 3 147 ) 148 149 // rtype is the common implementation of most values. 150 // It is embedded in other struct types. 151 // 152 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 153 type rtype struct { 154 size uintptr 155 ptrdata uintptr // number of bytes in the type that can contain pointers 156 hash uint32 // hash of type; avoids computation in hash tables 157 tflag tflag // extra type information flags 158 align uint8 // alignment of variable with this type 159 fieldAlign uint8 // alignment of struct field with this type 160 kind uint8 // enumeration for C 161 // function for comparing objects of this type 162 // (ptr to object A, ptr to object B) -> ==? 163 equal func(unsafe.Pointer, unsafe.Pointer) bool 164 gcdata *byte // garbage collection data 165 str nameOff // string form 166 ptrToThis typeOff // type for pointer to this type, may be zero 167 } 168 169 // Method on non-interface type 170 type method struct { 171 name nameOff // name of method 172 mtyp typeOff // method type (without receiver) 173 ifn textOff // fn used in interface call (one-word receiver) 174 tfn textOff // fn used for normal method call 175 } 176 177 // uncommonType is present only for defined types or types with methods 178 // (if T is a defined type, the uncommonTypes for T and *T have methods). 179 // Using a pointer to this struct reduces the overall size required 180 // to describe a non-defined type with no methods. 181 type uncommonType struct { 182 pkgPath nameOff // import path; empty for built-in types like int, string 183 mcount uint16 // number of methods 184 xcount uint16 // number of exported methods 185 moff uint32 // offset from this uncommontype to [mcount]method 186 _ uint32 // unused 187 } 188 189 // chanDir represents a channel type's direction. 190 type chanDir int 191 192 const ( 193 recvDir chanDir = 1 << iota // <-chan 194 sendDir // chan<- 195 bothDir = recvDir | sendDir // chan 196 ) 197 198 // arrayType represents a fixed array type. 199 type arrayType struct { 200 rtype 201 elem *rtype // array element type 202 slice *rtype // slice type 203 len uintptr 204 } 205 206 // chanType represents a channel type. 207 type chanType struct { 208 rtype 209 elem *rtype // channel element type 210 dir uintptr // channel direction (chanDir) 211 } 212 213 // funcType represents a function type. 214 // 215 // A *rtype for each in and out parameter is stored in an array that 216 // directly follows the funcType (and possibly its uncommonType). So 217 // a function type with one method, one input, and one output is: 218 // 219 // struct { 220 // funcType 221 // uncommonType 222 // [2]*rtype // [0] is in, [1] is out 223 // } 224 type funcType struct { 225 rtype 226 inCount uint16 227 outCount uint16 // top bit is set if last input parameter is ... 228 } 229 230 // imethod represents a method on an interface type 231 type imethod struct { 232 name nameOff // name of method 233 typ typeOff // .(*FuncType) underneath 234 } 235 236 // interfaceType represents an interface type. 237 type interfaceType struct { 238 rtype 239 pkgPath name // import path 240 methods []imethod // sorted by hash 241 } 242 243 // mapType represents a map type. 244 type mapType struct { 245 rtype 246 key *rtype // map key type 247 elem *rtype // map element (value) type 248 bucket *rtype // internal bucket structure 249 // function for hashing keys (ptr to key, seed) -> hash 250 hasher func(unsafe.Pointer, uintptr) uintptr 251 keysize uint8 // size of key slot 252 valuesize uint8 // size of value slot 253 bucketsize uint16 // size of bucket 254 flags uint32 255 } 256 257 // ptrType represents a pointer type. 258 type ptrType struct { 259 rtype 260 elem *rtype // pointer element (pointed at) type 261 } 262 263 // sliceType represents a slice type. 264 type sliceType struct { 265 rtype 266 elem *rtype // slice element type 267 } 268 269 // Struct field 270 type structField struct { 271 name name // name is always non-empty 272 typ *rtype // type of field 273 offsetEmbed uintptr // byte offset of field<<1 | isEmbedded 274 } 275 276 func (f *structField) offset() uintptr { 277 return f.offsetEmbed >> 1 278 } 279 280 func (f *structField) embedded() bool { 281 return f.offsetEmbed&1 != 0 282 } 283 284 // structType represents a struct type. 285 type structType struct { 286 rtype 287 pkgPath name 288 fields []structField // sorted by offset 289 } 290 291 // name is an encoded type name with optional extra data. 292 // 293 // The first byte is a bit field containing: 294 // 295 // 1<<0 the name is exported 296 // 1<<1 tag data follows the name 297 // 1<<2 pkgPath nameOff follows the name and tag 298 // 299 // The next two bytes are the data length: 300 // 301 // l := uint16(data[1])<<8 | uint16(data[2]) 302 // 303 // Bytes [3:3+l] are the string data. 304 // 305 // If tag data follows then bytes 3+l and 3+l+1 are the tag length, 306 // with the data following. 307 // 308 // If the import path follows, then 4 bytes at the end of 309 // the data form a nameOff. The import path is only set for concrete 310 // methods that are defined in a different package than their type. 311 // 312 // If a name starts with "*", then the exported bit represents 313 // whether the pointed to type is exported. 314 type name struct { 315 bytes *byte 316 } 317 318 func (n name) data(off int, whySafe string) *byte { 319 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) 320 } 321 322 func (n name) isExported() bool { 323 return (*n.bytes)&(1<<0) != 0 324 } 325 326 func (n name) hasTag() bool { 327 return (*n.bytes)&(1<<1) != 0 328 } 329 330 // readVarint parses a varint as encoded by encoding/binary. 331 // It returns the number of encoded bytes and the encoded value. 332 func (n name) readVarint(off int) (int, int) { 333 v := 0 334 for i := 0; ; i++ { 335 x := *n.data(off+i, "read varint") 336 v += int(x&0x7f) << (7 * i) 337 if x&0x80 == 0 { 338 return i + 1, v 339 } 340 } 341 } 342 343 func (n name) name() (s string) { 344 if n.bytes == nil { 345 return 346 } 347 i, l := n.readVarint(1) 348 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 349 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) 350 hdr.Len = l 351 return 352 } 353 354 func (n name) tag() (s string) { 355 if !n.hasTag() { 356 return "" 357 } 358 i, l := n.readVarint(1) 359 i2, l2 := n.readVarint(1 + i + l) 360 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 361 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string")) 362 hdr.Len = l2 363 return 364 } 365 366 func (n name) pkgPath() string { 367 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 368 return "" 369 } 370 i, l := n.readVarint(1) 371 off := 1 + i + l 372 if n.hasTag() { 373 i2, l2 := n.readVarint(off) 374 off += i2 + l2 375 } 376 var nameOff int32 377 // Note that this field may not be aligned in memory, 378 // so we cannot use a direct int32 assignment here. 379 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 380 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 381 return pkgPathName.name() 382 } 383 384 /* 385 * The compiler knows the exact layout of all the data structures above. 386 * The compiler does not know about the data structures and methods below. 387 */ 388 389 const ( 390 kindDirectIface = 1 << 5 391 kindGCProg = 1 << 6 // Type.gc points to GC program 392 kindMask = (1 << 5) - 1 393 ) 394 395 // String returns the name of k. 396 func (k Kind) String() string { 397 if int(k) < len(kindNames) { 398 return kindNames[k] 399 } 400 return kindNames[0] 401 } 402 403 var kindNames = []string{ 404 Invalid: "invalid", 405 Bool: "bool", 406 Int: "int", 407 Int8: "int8", 408 Int16: "int16", 409 Int32: "int32", 410 Int64: "int64", 411 Uint: "uint", 412 Uint8: "uint8", 413 Uint16: "uint16", 414 Uint32: "uint32", 415 Uint64: "uint64", 416 Uintptr: "uintptr", 417 Float32: "float32", 418 Float64: "float64", 419 Complex64: "complex64", 420 Complex128: "complex128", 421 Array: "array", 422 Chan: "chan", 423 Func: "func", 424 Interface: "interface", 425 Map: "map", 426 Ptr: "ptr", 427 Slice: "slice", 428 String: "string", 429 Struct: "struct", 430 UnsafePointer: "unsafe.Pointer", 431 } 432 433 func (t *uncommonType) methods() []method { 434 if t.mcount == 0 { 435 return nil 436 } 437 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 438 } 439 440 func (t *uncommonType) exportedMethods() []method { 441 if t.xcount == 0 { 442 return nil 443 } 444 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 445 } 446 447 // resolveNameOff resolves a name offset from a base pointer. 448 // The (*rtype).nameOff method is a convenience wrapper for this function. 449 // Implemented in the runtime package. 450 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 451 452 // resolveTypeOff resolves an *rtype offset from a base type. 453 // The (*rtype).typeOff method is a convenience wrapper for this function. 454 // Implemented in the runtime package. 455 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 456 457 type nameOff int32 // offset to a name 458 type typeOff int32 // offset to an *rtype 459 type textOff int32 // offset from top of text section 460 461 func (t *rtype) nameOff(off nameOff) name { 462 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 463 } 464 465 func (t *rtype) typeOff(off typeOff) *rtype { 466 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 467 } 468 469 func (t *rtype) uncommon() *uncommonType { 470 if t.tflag&tflagUncommon == 0 { 471 return nil 472 } 473 switch t.Kind() { 474 case Struct: 475 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 476 case Ptr: 477 type u struct { 478 ptrType 479 u uncommonType 480 } 481 return &(*u)(unsafe.Pointer(t)).u 482 case Func: 483 type u struct { 484 funcType 485 u uncommonType 486 } 487 return &(*u)(unsafe.Pointer(t)).u 488 case Slice: 489 type u struct { 490 sliceType 491 u uncommonType 492 } 493 return &(*u)(unsafe.Pointer(t)).u 494 case Array: 495 type u struct { 496 arrayType 497 u uncommonType 498 } 499 return &(*u)(unsafe.Pointer(t)).u 500 case Chan: 501 type u struct { 502 chanType 503 u uncommonType 504 } 505 return &(*u)(unsafe.Pointer(t)).u 506 case Map: 507 type u struct { 508 mapType 509 u uncommonType 510 } 511 return &(*u)(unsafe.Pointer(t)).u 512 case Interface: 513 type u struct { 514 interfaceType 515 u uncommonType 516 } 517 return &(*u)(unsafe.Pointer(t)).u 518 default: 519 type u struct { 520 rtype 521 u uncommonType 522 } 523 return &(*u)(unsafe.Pointer(t)).u 524 } 525 } 526 527 func (t *rtype) String() string { 528 s := t.nameOff(t.str).name() 529 if t.tflag&tflagExtraStar != 0 { 530 return s[1:] 531 } 532 return s 533 } 534 535 func (t *rtype) Size() uintptr { return t.size } 536 537 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 538 539 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 540 541 func (t *rtype) common() *rtype { return t } 542 543 func (t *rtype) exportedMethods() []method { 544 ut := t.uncommon() 545 if ut == nil { 546 return nil 547 } 548 return ut.exportedMethods() 549 } 550 551 func (t *rtype) NumMethod() int { 552 if t.Kind() == Interface { 553 tt := (*interfaceType)(unsafe.Pointer(t)) 554 return tt.NumMethod() 555 } 556 return len(t.exportedMethods()) 557 } 558 559 func (t *rtype) PkgPath() string { 560 if t.tflag&tflagNamed == 0 { 561 return "" 562 } 563 ut := t.uncommon() 564 if ut == nil { 565 return "" 566 } 567 return t.nameOff(ut.pkgPath).name() 568 } 569 570 func (t *rtype) hasName() bool { 571 return t.tflag&tflagNamed != 0 572 } 573 574 func (t *rtype) Name() string { 575 if !t.hasName() { 576 return "" 577 } 578 s := t.String() 579 i := len(s) - 1 580 for i >= 0 && s[i] != '.' { 581 i-- 582 } 583 return s[i+1:] 584 } 585 586 func (t *rtype) chanDir() chanDir { 587 if t.Kind() != Chan { 588 panic("reflect: chanDir of non-chan type") 589 } 590 tt := (*chanType)(unsafe.Pointer(t)) 591 return chanDir(tt.dir) 592 } 593 594 func (t *rtype) Elem() Type { 595 switch t.Kind() { 596 case Array: 597 tt := (*arrayType)(unsafe.Pointer(t)) 598 return toType(tt.elem) 599 case Chan: 600 tt := (*chanType)(unsafe.Pointer(t)) 601 return toType(tt.elem) 602 case Map: 603 tt := (*mapType)(unsafe.Pointer(t)) 604 return toType(tt.elem) 605 case Ptr: 606 tt := (*ptrType)(unsafe.Pointer(t)) 607 return toType(tt.elem) 608 case Slice: 609 tt := (*sliceType)(unsafe.Pointer(t)) 610 return toType(tt.elem) 611 } 612 panic("reflect: Elem of invalid type") 613 } 614 615 func (t *rtype) In(i int) Type { 616 if t.Kind() != Func { 617 panic("reflect: In of non-func type") 618 } 619 tt := (*funcType)(unsafe.Pointer(t)) 620 return toType(tt.in()[i]) 621 } 622 623 func (t *rtype) Key() Type { 624 if t.Kind() != Map { 625 panic("reflect: Key of non-map type") 626 } 627 tt := (*mapType)(unsafe.Pointer(t)) 628 return toType(tt.key) 629 } 630 631 func (t *rtype) Len() int { 632 if t.Kind() != Array { 633 panic("reflect: Len of non-array type") 634 } 635 tt := (*arrayType)(unsafe.Pointer(t)) 636 return int(tt.len) 637 } 638 639 func (t *rtype) NumField() int { 640 if t.Kind() != Struct { 641 panic("reflect: NumField of non-struct type") 642 } 643 tt := (*structType)(unsafe.Pointer(t)) 644 return len(tt.fields) 645 } 646 647 func (t *rtype) NumIn() int { 648 if t.Kind() != Func { 649 panic("reflect: NumIn of non-func type") 650 } 651 tt := (*funcType)(unsafe.Pointer(t)) 652 return int(tt.inCount) 653 } 654 655 func (t *rtype) NumOut() int { 656 if t.Kind() != Func { 657 panic("reflect: NumOut of non-func type") 658 } 659 tt := (*funcType)(unsafe.Pointer(t)) 660 return len(tt.out()) 661 } 662 663 func (t *rtype) Out(i int) Type { 664 if t.Kind() != Func { 665 panic("reflect: Out of non-func type") 666 } 667 tt := (*funcType)(unsafe.Pointer(t)) 668 return toType(tt.out()[i]) 669 } 670 671 func (t *funcType) in() []*rtype { 672 uadd := unsafe.Sizeof(*t) 673 if t.tflag&tflagUncommon != 0 { 674 uadd += unsafe.Sizeof(uncommonType{}) 675 } 676 if t.inCount == 0 { 677 return nil 678 } 679 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 680 } 681 682 func (t *funcType) out() []*rtype { 683 uadd := unsafe.Sizeof(*t) 684 if t.tflag&tflagUncommon != 0 { 685 uadd += unsafe.Sizeof(uncommonType{}) 686 } 687 outCount := t.outCount & (1<<15 - 1) 688 if outCount == 0 { 689 return nil 690 } 691 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 692 } 693 694 // add returns p+x. 695 // 696 // The whySafe string is ignored, so that the function still inlines 697 // as efficiently as p+x, but all call sites should use the string to 698 // record why the addition is safe, which is to say why the addition 699 // does not cause x to advance to the very end of p's allocation 700 // and therefore point incorrectly at the next block in memory. 701 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 702 return unsafe.Pointer(uintptr(p) + x) 703 } 704 705 // NumMethod returns the number of interface methods in the type's method set. 706 func (t *interfaceType) NumMethod() int { return len(t.methods) } 707 708 // TypeOf returns the reflection Type that represents the dynamic type of i. 709 // If i is a nil interface value, TypeOf returns nil. 710 func TypeOf(i interface{}) Type { 711 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 712 return toType(eface.typ) 713 } 714 715 func (t *rtype) Implements(u Type) bool { 716 if u == nil { 717 panic("reflect: nil type passed to Type.Implements") 718 } 719 if u.Kind() != Interface { 720 panic("reflect: non-interface type passed to Type.Implements") 721 } 722 return implements(u.(*rtype), t) 723 } 724 725 func (t *rtype) AssignableTo(u Type) bool { 726 if u == nil { 727 panic("reflect: nil type passed to Type.AssignableTo") 728 } 729 uu := u.(*rtype) 730 return directlyAssignable(uu, t) || implements(uu, t) 731 } 732 733 func (t *rtype) Comparable() bool { 734 return t.equal != nil 735 } 736 737 // implements reports whether the type V implements the interface type T. 738 func implements(T, V *rtype) bool { 739 if T.Kind() != Interface { 740 return false 741 } 742 t := (*interfaceType)(unsafe.Pointer(T)) 743 if len(t.methods) == 0 { 744 return true 745 } 746 747 // The same algorithm applies in both cases, but the 748 // method tables for an interface type and a concrete type 749 // are different, so the code is duplicated. 750 // In both cases the algorithm is a linear scan over the two 751 // lists - T's methods and V's methods - simultaneously. 752 // Since method tables are stored in a unique sorted order 753 // (alphabetical, with no duplicate method names), the scan 754 // through V's methods must hit a match for each of T's 755 // methods along the way, or else V does not implement T. 756 // This lets us run the scan in overall linear time instead of 757 // the quadratic time a naive search would require. 758 // See also ../runtime/iface.go. 759 if V.Kind() == Interface { 760 v := (*interfaceType)(unsafe.Pointer(V)) 761 i := 0 762 for j := 0; j < len(v.methods); j++ { 763 tm := &t.methods[i] 764 tmName := t.nameOff(tm.name) 765 vm := &v.methods[j] 766 vmName := V.nameOff(vm.name) 767 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) { 768 if !tmName.isExported() { 769 tmPkgPath := tmName.pkgPath() 770 if tmPkgPath == "" { 771 tmPkgPath = t.pkgPath.name() 772 } 773 vmPkgPath := vmName.pkgPath() 774 if vmPkgPath == "" { 775 vmPkgPath = v.pkgPath.name() 776 } 777 if tmPkgPath != vmPkgPath { 778 continue 779 } 780 } 781 if i++; i >= len(t.methods) { 782 return true 783 } 784 } 785 } 786 return false 787 } 788 789 v := V.uncommon() 790 if v == nil { 791 return false 792 } 793 i := 0 794 vmethods := v.methods() 795 for j := 0; j < int(v.mcount); j++ { 796 tm := &t.methods[i] 797 tmName := t.nameOff(tm.name) 798 vm := vmethods[j] 799 vmName := V.nameOff(vm.name) 800 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 801 if !tmName.isExported() { 802 tmPkgPath := tmName.pkgPath() 803 if tmPkgPath == "" { 804 tmPkgPath = t.pkgPath.name() 805 } 806 vmPkgPath := vmName.pkgPath() 807 if vmPkgPath == "" { 808 vmPkgPath = V.nameOff(v.pkgPath).name() 809 } 810 if tmPkgPath != vmPkgPath { 811 continue 812 } 813 } 814 if i++; i >= len(t.methods) { 815 return true 816 } 817 } 818 } 819 return false 820 } 821 822 // directlyAssignable reports whether a value x of type V can be directly 823 // assigned (using memmove) to a value of type T. 824 // https://golang.org/doc/go_spec.html#Assignability 825 // Ignoring the interface rules (implemented elsewhere) 826 // and the ideal constant rules (no ideal constants at run time). 827 func directlyAssignable(T, V *rtype) bool { 828 // x's type V is identical to T? 829 if T == V { 830 return true 831 } 832 833 // Otherwise at least one of T and V must not be defined 834 // and they must have the same kind. 835 if T.hasName() && V.hasName() || T.Kind() != V.Kind() { 836 return false 837 } 838 839 // x's type T and V must have identical underlying types. 840 return haveIdenticalUnderlyingType(T, V, true) 841 } 842 843 func haveIdenticalType(T, V Type, cmpTags bool) bool { 844 if cmpTags { 845 return T == V 846 } 847 848 if T.Name() != V.Name() || T.Kind() != V.Kind() { 849 return false 850 } 851 852 return haveIdenticalUnderlyingType(T.common(), V.common(), false) 853 } 854 855 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { 856 if T == V { 857 return true 858 } 859 860 kind := T.Kind() 861 if kind != V.Kind() { 862 return false 863 } 864 865 // Non-composite types of equal kind have same underlying type 866 // (the predefined instance of the type). 867 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 868 return true 869 } 870 871 // Composite types. 872 switch kind { 873 case Array: 874 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 875 876 case Chan: 877 // Special case: 878 // x is a bidirectional channel value, T is a channel type, 879 // and x's type V and T have identical element types. 880 if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) { 881 return true 882 } 883 884 // Otherwise continue test for identical underlying type. 885 return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 886 887 case Func: 888 t := (*funcType)(unsafe.Pointer(T)) 889 v := (*funcType)(unsafe.Pointer(V)) 890 if t.outCount != v.outCount || t.inCount != v.inCount { 891 return false 892 } 893 for i := 0; i < t.NumIn(); i++ { 894 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) { 895 return false 896 } 897 } 898 for i := 0; i < t.NumOut(); i++ { 899 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) { 900 return false 901 } 902 } 903 return true 904 905 case Interface: 906 t := (*interfaceType)(unsafe.Pointer(T)) 907 v := (*interfaceType)(unsafe.Pointer(V)) 908 if len(t.methods) == 0 && len(v.methods) == 0 { 909 return true 910 } 911 // Might have the same methods but still 912 // need a run time conversion. 913 return false 914 915 case Map: 916 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 917 918 case Ptr, Slice: 919 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 920 921 case Struct: 922 t := (*structType)(unsafe.Pointer(T)) 923 v := (*structType)(unsafe.Pointer(V)) 924 if len(t.fields) != len(v.fields) { 925 return false 926 } 927 if t.pkgPath.name() != v.pkgPath.name() { 928 return false 929 } 930 for i := range t.fields { 931 tf := &t.fields[i] 932 vf := &v.fields[i] 933 if tf.name.name() != vf.name.name() { 934 return false 935 } 936 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) { 937 return false 938 } 939 if cmpTags && tf.name.tag() != vf.name.tag() { 940 return false 941 } 942 if tf.offsetEmbed != vf.offsetEmbed { 943 return false 944 } 945 } 946 return true 947 } 948 949 return false 950 } 951 952 type structTypeUncommon struct { 953 structType 954 u uncommonType 955 } 956 957 // toType converts from a *rtype to a Type that can be returned 958 // to the client of package reflect. In gc, the only concern is that 959 // a nil *rtype must be replaced by a nil Type, but in gccgo this 960 // function takes care of ensuring that multiple *rtype for the same 961 // type are coalesced into a single Type. 962 func toType(t *rtype) Type { 963 if t == nil { 964 return nil 965 } 966 return t 967 } 968 969 // ifaceIndir reports whether t is stored indirectly in an interface value. 970 func ifaceIndir(t *rtype) bool { 971 return t.kind&kindDirectIface == 0 972 }