github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/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/gc/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/gc/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) nameLen() int { 325 return int(uint16(*n.data(1, "name len field"))<<8 | uint16(*n.data(2, "name len field"))) 326 } 327 328 func (n name) tagLen() int { 329 if *n.data(0, "name flag field")&(1<<1) == 0 { 330 return 0 331 } 332 off := 3 + n.nameLen() 333 return int(uint16(*n.data(off, "name taglen field"))<<8 | uint16(*n.data(off+1, "name taglen field"))) 334 } 335 336 func (n name) name() (s string) { 337 if n.bytes == nil { 338 return 339 } 340 b := (*[4]byte)(unsafe.Pointer(n.bytes)) 341 342 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 343 hdr.Data = unsafe.Pointer(&b[3]) 344 hdr.Len = int(b[1])<<8 | int(b[2]) 345 return s 346 } 347 348 func (n name) tag() (s string) { 349 tl := n.tagLen() 350 if tl == 0 { 351 return "" 352 } 353 nl := n.nameLen() 354 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 355 hdr.Data = unsafe.Pointer(n.data(3+nl+2, "non-empty string")) 356 hdr.Len = tl 357 return s 358 } 359 360 func (n name) pkgPath() string { 361 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 362 return "" 363 } 364 off := 3 + n.nameLen() 365 if tl := n.tagLen(); tl > 0 { 366 off += 2 + tl 367 } 368 var nameOff int32 369 // Note that this field may not be aligned in memory, 370 // so we cannot use a direct int32 assignment here. 371 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 372 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 373 return pkgPathName.name() 374 } 375 376 /* 377 * The compiler knows the exact layout of all the data structures above. 378 * The compiler does not know about the data structures and methods below. 379 */ 380 381 const ( 382 kindDirectIface = 1 << 5 383 kindGCProg = 1 << 6 // Type.gc points to GC program 384 kindMask = (1 << 5) - 1 385 ) 386 387 // String returns the name of k. 388 func (k Kind) String() string { 389 if int(k) < len(kindNames) { 390 return kindNames[k] 391 } 392 return kindNames[0] 393 } 394 395 var kindNames = []string{ 396 Invalid: "invalid", 397 Bool: "bool", 398 Int: "int", 399 Int8: "int8", 400 Int16: "int16", 401 Int32: "int32", 402 Int64: "int64", 403 Uint: "uint", 404 Uint8: "uint8", 405 Uint16: "uint16", 406 Uint32: "uint32", 407 Uint64: "uint64", 408 Uintptr: "uintptr", 409 Float32: "float32", 410 Float64: "float64", 411 Complex64: "complex64", 412 Complex128: "complex128", 413 Array: "array", 414 Chan: "chan", 415 Func: "func", 416 Interface: "interface", 417 Map: "map", 418 Ptr: "ptr", 419 Slice: "slice", 420 String: "string", 421 Struct: "struct", 422 UnsafePointer: "unsafe.Pointer", 423 } 424 425 func (t *uncommonType) methods() []method { 426 if t.mcount == 0 { 427 return nil 428 } 429 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 430 } 431 432 func (t *uncommonType) exportedMethods() []method { 433 if t.xcount == 0 { 434 return nil 435 } 436 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 437 } 438 439 // resolveNameOff resolves a name offset from a base pointer. 440 // The (*rtype).nameOff method is a convenience wrapper for this function. 441 // Implemented in the runtime package. 442 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 443 444 // resolveTypeOff resolves an *rtype offset from a base type. 445 // The (*rtype).typeOff method is a convenience wrapper for this function. 446 // Implemented in the runtime package. 447 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 448 449 type nameOff int32 // offset to a name 450 type typeOff int32 // offset to an *rtype 451 type textOff int32 // offset from top of text section 452 453 func (t *rtype) nameOff(off nameOff) name { 454 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 455 } 456 457 func (t *rtype) typeOff(off typeOff) *rtype { 458 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 459 } 460 461 func (t *rtype) uncommon() *uncommonType { 462 if t.tflag&tflagUncommon == 0 { 463 return nil 464 } 465 switch t.Kind() { 466 case Struct: 467 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 468 case Ptr: 469 type u struct { 470 ptrType 471 u uncommonType 472 } 473 return &(*u)(unsafe.Pointer(t)).u 474 case Func: 475 type u struct { 476 funcType 477 u uncommonType 478 } 479 return &(*u)(unsafe.Pointer(t)).u 480 case Slice: 481 type u struct { 482 sliceType 483 u uncommonType 484 } 485 return &(*u)(unsafe.Pointer(t)).u 486 case Array: 487 type u struct { 488 arrayType 489 u uncommonType 490 } 491 return &(*u)(unsafe.Pointer(t)).u 492 case Chan: 493 type u struct { 494 chanType 495 u uncommonType 496 } 497 return &(*u)(unsafe.Pointer(t)).u 498 case Map: 499 type u struct { 500 mapType 501 u uncommonType 502 } 503 return &(*u)(unsafe.Pointer(t)).u 504 case Interface: 505 type u struct { 506 interfaceType 507 u uncommonType 508 } 509 return &(*u)(unsafe.Pointer(t)).u 510 default: 511 type u struct { 512 rtype 513 u uncommonType 514 } 515 return &(*u)(unsafe.Pointer(t)).u 516 } 517 } 518 519 func (t *rtype) String() string { 520 s := t.nameOff(t.str).name() 521 if t.tflag&tflagExtraStar != 0 { 522 return s[1:] 523 } 524 return s 525 } 526 527 func (t *rtype) Size() uintptr { return t.size } 528 529 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 530 531 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 532 533 func (t *rtype) common() *rtype { return t } 534 535 func (t *rtype) exportedMethods() []method { 536 ut := t.uncommon() 537 if ut == nil { 538 return nil 539 } 540 return ut.exportedMethods() 541 } 542 543 func (t *rtype) NumMethod() int { 544 if t.Kind() == Interface { 545 tt := (*interfaceType)(unsafe.Pointer(t)) 546 return tt.NumMethod() 547 } 548 return len(t.exportedMethods()) 549 } 550 551 func (t *rtype) PkgPath() string { 552 if t.tflag&tflagNamed == 0 { 553 return "" 554 } 555 ut := t.uncommon() 556 if ut == nil { 557 return "" 558 } 559 return t.nameOff(ut.pkgPath).name() 560 } 561 562 func (t *rtype) hasName() bool { 563 return t.tflag&tflagNamed != 0 564 } 565 566 func (t *rtype) Name() string { 567 if !t.hasName() { 568 return "" 569 } 570 s := t.String() 571 i := len(s) - 1 572 for i >= 0 && s[i] != '.' { 573 i-- 574 } 575 return s[i+1:] 576 } 577 578 func (t *rtype) chanDir() chanDir { 579 if t.Kind() != Chan { 580 panic("reflect: chanDir of non-chan type") 581 } 582 tt := (*chanType)(unsafe.Pointer(t)) 583 return chanDir(tt.dir) 584 } 585 586 func (t *rtype) Elem() Type { 587 switch t.Kind() { 588 case Array: 589 tt := (*arrayType)(unsafe.Pointer(t)) 590 return toType(tt.elem) 591 case Chan: 592 tt := (*chanType)(unsafe.Pointer(t)) 593 return toType(tt.elem) 594 case Map: 595 tt := (*mapType)(unsafe.Pointer(t)) 596 return toType(tt.elem) 597 case Ptr: 598 tt := (*ptrType)(unsafe.Pointer(t)) 599 return toType(tt.elem) 600 case Slice: 601 tt := (*sliceType)(unsafe.Pointer(t)) 602 return toType(tt.elem) 603 } 604 panic("reflect: Elem of invalid type") 605 } 606 607 func (t *rtype) In(i int) Type { 608 if t.Kind() != Func { 609 panic("reflect: In of non-func type") 610 } 611 tt := (*funcType)(unsafe.Pointer(t)) 612 return toType(tt.in()[i]) 613 } 614 615 func (t *rtype) Key() Type { 616 if t.Kind() != Map { 617 panic("reflect: Key of non-map type") 618 } 619 tt := (*mapType)(unsafe.Pointer(t)) 620 return toType(tt.key) 621 } 622 623 func (t *rtype) Len() int { 624 if t.Kind() != Array { 625 panic("reflect: Len of non-array type") 626 } 627 tt := (*arrayType)(unsafe.Pointer(t)) 628 return int(tt.len) 629 } 630 631 func (t *rtype) NumField() int { 632 if t.Kind() != Struct { 633 panic("reflect: NumField of non-struct type") 634 } 635 tt := (*structType)(unsafe.Pointer(t)) 636 return len(tt.fields) 637 } 638 639 func (t *rtype) NumIn() int { 640 if t.Kind() != Func { 641 panic("reflect: NumIn of non-func type") 642 } 643 tt := (*funcType)(unsafe.Pointer(t)) 644 return int(tt.inCount) 645 } 646 647 func (t *rtype) NumOut() int { 648 if t.Kind() != Func { 649 panic("reflect: NumOut of non-func type") 650 } 651 tt := (*funcType)(unsafe.Pointer(t)) 652 return len(tt.out()) 653 } 654 655 func (t *rtype) Out(i int) Type { 656 if t.Kind() != Func { 657 panic("reflect: Out of non-func type") 658 } 659 tt := (*funcType)(unsafe.Pointer(t)) 660 return toType(tt.out()[i]) 661 } 662 663 func (t *funcType) in() []*rtype { 664 uadd := unsafe.Sizeof(*t) 665 if t.tflag&tflagUncommon != 0 { 666 uadd += unsafe.Sizeof(uncommonType{}) 667 } 668 if t.inCount == 0 { 669 return nil 670 } 671 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 672 } 673 674 func (t *funcType) out() []*rtype { 675 uadd := unsafe.Sizeof(*t) 676 if t.tflag&tflagUncommon != 0 { 677 uadd += unsafe.Sizeof(uncommonType{}) 678 } 679 outCount := t.outCount & (1<<15 - 1) 680 if outCount == 0 { 681 return nil 682 } 683 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 684 } 685 686 // add returns p+x. 687 // 688 // The whySafe string is ignored, so that the function still inlines 689 // as efficiently as p+x, but all call sites should use the string to 690 // record why the addition is safe, which is to say why the addition 691 // does not cause x to advance to the very end of p's allocation 692 // and therefore point incorrectly at the next block in memory. 693 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 694 return unsafe.Pointer(uintptr(p) + x) 695 } 696 697 // NumMethod returns the number of interface methods in the type's method set. 698 func (t *interfaceType) NumMethod() int { return len(t.methods) } 699 700 // TypeOf returns the reflection Type that represents the dynamic type of i. 701 // If i is a nil interface value, TypeOf returns nil. 702 func TypeOf(i interface{}) Type { 703 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 704 return toType(eface.typ) 705 } 706 707 func (t *rtype) Implements(u Type) bool { 708 if u == nil { 709 panic("reflect: nil type passed to Type.Implements") 710 } 711 if u.Kind() != Interface { 712 panic("reflect: non-interface type passed to Type.Implements") 713 } 714 return implements(u.(*rtype), t) 715 } 716 717 func (t *rtype) AssignableTo(u Type) bool { 718 if u == nil { 719 panic("reflect: nil type passed to Type.AssignableTo") 720 } 721 uu := u.(*rtype) 722 return directlyAssignable(uu, t) || implements(uu, t) 723 } 724 725 func (t *rtype) Comparable() bool { 726 return t.equal != nil 727 } 728 729 // implements reports whether the type V implements the interface type T. 730 func implements(T, V *rtype) bool { 731 if T.Kind() != Interface { 732 return false 733 } 734 t := (*interfaceType)(unsafe.Pointer(T)) 735 if len(t.methods) == 0 { 736 return true 737 } 738 739 // The same algorithm applies in both cases, but the 740 // method tables for an interface type and a concrete type 741 // are different, so the code is duplicated. 742 // In both cases the algorithm is a linear scan over the two 743 // lists - T's methods and V's methods - simultaneously. 744 // Since method tables are stored in a unique sorted order 745 // (alphabetical, with no duplicate method names), the scan 746 // through V's methods must hit a match for each of T's 747 // methods along the way, or else V does not implement T. 748 // This lets us run the scan in overall linear time instead of 749 // the quadratic time a naive search would require. 750 // See also ../runtime/iface.go. 751 if V.Kind() == Interface { 752 v := (*interfaceType)(unsafe.Pointer(V)) 753 i := 0 754 for j := 0; j < len(v.methods); j++ { 755 tm := &t.methods[i] 756 tmName := t.nameOff(tm.name) 757 vm := &v.methods[j] 758 vmName := V.nameOff(vm.name) 759 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) { 760 if !tmName.isExported() { 761 tmPkgPath := tmName.pkgPath() 762 if tmPkgPath == "" { 763 tmPkgPath = t.pkgPath.name() 764 } 765 vmPkgPath := vmName.pkgPath() 766 if vmPkgPath == "" { 767 vmPkgPath = v.pkgPath.name() 768 } 769 if tmPkgPath != vmPkgPath { 770 continue 771 } 772 } 773 if i++; i >= len(t.methods) { 774 return true 775 } 776 } 777 } 778 return false 779 } 780 781 v := V.uncommon() 782 if v == nil { 783 return false 784 } 785 i := 0 786 vmethods := v.methods() 787 for j := 0; j < int(v.mcount); j++ { 788 tm := &t.methods[i] 789 tmName := t.nameOff(tm.name) 790 vm := vmethods[j] 791 vmName := V.nameOff(vm.name) 792 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 793 if !tmName.isExported() { 794 tmPkgPath := tmName.pkgPath() 795 if tmPkgPath == "" { 796 tmPkgPath = t.pkgPath.name() 797 } 798 vmPkgPath := vmName.pkgPath() 799 if vmPkgPath == "" { 800 vmPkgPath = V.nameOff(v.pkgPath).name() 801 } 802 if tmPkgPath != vmPkgPath { 803 continue 804 } 805 } 806 if i++; i >= len(t.methods) { 807 return true 808 } 809 } 810 } 811 return false 812 } 813 814 // directlyAssignable reports whether a value x of type V can be directly 815 // assigned (using memmove) to a value of type T. 816 // https://golang.org/doc/go_spec.html#Assignability 817 // Ignoring the interface rules (implemented elsewhere) 818 // and the ideal constant rules (no ideal constants at run time). 819 func directlyAssignable(T, V *rtype) bool { 820 // x's type V is identical to T? 821 if T == V { 822 return true 823 } 824 825 // Otherwise at least one of T and V must not be defined 826 // and they must have the same kind. 827 if T.hasName() && V.hasName() || T.Kind() != V.Kind() { 828 return false 829 } 830 831 // x's type T and V must have identical underlying types. 832 return haveIdenticalUnderlyingType(T, V, true) 833 } 834 835 func haveIdenticalType(T, V Type, cmpTags bool) bool { 836 if cmpTags { 837 return T == V 838 } 839 840 if T.Name() != V.Name() || T.Kind() != V.Kind() { 841 return false 842 } 843 844 return haveIdenticalUnderlyingType(T.common(), V.common(), false) 845 } 846 847 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { 848 if T == V { 849 return true 850 } 851 852 kind := T.Kind() 853 if kind != V.Kind() { 854 return false 855 } 856 857 // Non-composite types of equal kind have same underlying type 858 // (the predefined instance of the type). 859 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 860 return true 861 } 862 863 // Composite types. 864 switch kind { 865 case Array: 866 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 867 868 case Chan: 869 // Special case: 870 // x is a bidirectional channel value, T is a channel type, 871 // and x's type V and T have identical element types. 872 if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) { 873 return true 874 } 875 876 // Otherwise continue test for identical underlying type. 877 return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 878 879 case Func: 880 t := (*funcType)(unsafe.Pointer(T)) 881 v := (*funcType)(unsafe.Pointer(V)) 882 if t.outCount != v.outCount || t.inCount != v.inCount { 883 return false 884 } 885 for i := 0; i < t.NumIn(); i++ { 886 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) { 887 return false 888 } 889 } 890 for i := 0; i < t.NumOut(); i++ { 891 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) { 892 return false 893 } 894 } 895 return true 896 897 case Interface: 898 t := (*interfaceType)(unsafe.Pointer(T)) 899 v := (*interfaceType)(unsafe.Pointer(V)) 900 if len(t.methods) == 0 && len(v.methods) == 0 { 901 return true 902 } 903 // Might have the same methods but still 904 // need a run time conversion. 905 return false 906 907 case Map: 908 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 909 910 case Ptr, Slice: 911 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 912 913 case Struct: 914 t := (*structType)(unsafe.Pointer(T)) 915 v := (*structType)(unsafe.Pointer(V)) 916 if len(t.fields) != len(v.fields) { 917 return false 918 } 919 if t.pkgPath.name() != v.pkgPath.name() { 920 return false 921 } 922 for i := range t.fields { 923 tf := &t.fields[i] 924 vf := &v.fields[i] 925 if tf.name.name() != vf.name.name() { 926 return false 927 } 928 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) { 929 return false 930 } 931 if cmpTags && tf.name.tag() != vf.name.tag() { 932 return false 933 } 934 if tf.offsetEmbed != vf.offsetEmbed { 935 return false 936 } 937 } 938 return true 939 } 940 941 return false 942 } 943 944 type structTypeUncommon struct { 945 structType 946 u uncommonType 947 } 948 949 // toType converts from a *rtype to a Type that can be returned 950 // to the client of package reflect. In gc, the only concern is that 951 // a nil *rtype must be replaced by a nil Type, but in gccgo this 952 // function takes care of ensuring that multiple *rtype for the same 953 // type are coalesced into a single Type. 954 func toType(t *rtype) Type { 955 if t == nil { 956 return nil 957 } 958 return t 959 } 960 961 // ifaceIndir reports whether t is stored indirectly in an interface value. 962 func ifaceIndir(t *rtype) bool { 963 return t.kind&kindDirectIface == 0 964 }