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