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