github.com/JimmyHuang454/JLS-go@v0.0.0-20230831150107-90d536585ba0/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 "unsafe" 10 11 // Type is the representation of a Go type. 12 // 13 // Not all methods apply to all kinds of types. Restrictions, 14 // if any, are noted in the documentation for each method. 15 // Use the Kind method to find out the kind of type before 16 // calling kind-specific methods. Calling a method 17 // inappropriate to the kind of type causes a run-time panic. 18 // 19 // Type values are comparable, such as with the == operator, 20 // so they can be used as map keys. 21 // Two Type values are equal if they represent identical types. 22 type Type interface { 23 // Methods applicable to all types. 24 25 // Name returns the type's name within its package for a defined type. 26 // For other (non-defined) types it returns the empty string. 27 Name() string 28 29 // PkgPath returns a defined type's package path, that is, the import path 30 // that uniquely identifies the package, such as "encoding/base64". 31 // If the type was predeclared (string, error) or not defined (*T, struct{}, 32 // []int, or A where A is an alias for a non-defined type), the package path 33 // will be the empty string. 34 PkgPath() string 35 36 // Size returns the number of bytes needed to store 37 // a value of the given type; it is analogous to unsafe.Sizeof. 38 Size() uintptr 39 40 // Kind returns the specific kind of this type. 41 Kind() Kind 42 43 // Implements reports whether the type implements the interface type u. 44 Implements(u Type) bool 45 46 // AssignableTo reports whether a value of the type is assignable to type u. 47 AssignableTo(u Type) bool 48 49 // Comparable reports whether values of this type are comparable. 50 Comparable() bool 51 52 // String returns a string representation of the type. 53 // The string representation may use shortened package names 54 // (e.g., base64 instead of "encoding/base64") and is not 55 // guaranteed to be unique among types. To test for type identity, 56 // compare the Types directly. 57 String() string 58 59 // Elem returns a type's element type. 60 // It panics if the type's Kind is not Ptr. 61 Elem() Type 62 63 common() *rtype 64 uncommon() *uncommonType 65 } 66 67 /* 68 * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go). 69 * A few are known to ../runtime/type.go to convey to debuggers. 70 * They are also known to ../runtime/type.go. 71 */ 72 73 // A Kind represents the specific kind of type that a Type represents. 74 // The zero Kind is not a valid kind. 75 type Kind uint 76 77 const ( 78 Invalid Kind = iota 79 Bool 80 Int 81 Int8 82 Int16 83 Int32 84 Int64 85 Uint 86 Uint8 87 Uint16 88 Uint32 89 Uint64 90 Uintptr 91 Float32 92 Float64 93 Complex64 94 Complex128 95 Array 96 Chan 97 Func 98 Interface 99 Map 100 Pointer 101 Slice 102 String 103 Struct 104 UnsafePointer 105 ) 106 107 const Ptr = Pointer 108 109 // tflag is used by an rtype to signal what extra type information is 110 // available in the memory directly following the rtype value. 111 // 112 // tflag values must be kept in sync with copies in: 113 // 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 offset uintptr // byte offset of field 272 } 273 274 func (f *structField) embedded() bool { 275 return f.name.embedded() 276 } 277 278 // structType represents a struct type. 279 type structType struct { 280 rtype 281 pkgPath name 282 fields []structField // sorted by offset 283 } 284 285 // name is an encoded type name with optional extra data. 286 // 287 // The first byte is a bit field containing: 288 // 289 // 1<<0 the name is exported 290 // 1<<1 tag data follows the name 291 // 1<<2 pkgPath nameOff follows the name and tag 292 // 293 // The next two bytes are the data length: 294 // 295 // l := uint16(data[1])<<8 | uint16(data[2]) 296 // 297 // Bytes [3:3+l] are the string data. 298 // 299 // If tag data follows then bytes 3+l and 3+l+1 are the tag length, 300 // with the data following. 301 // 302 // If the import path follows, then 4 bytes at the end of 303 // the data form a nameOff. The import path is only set for concrete 304 // methods that are defined in a different package than their type. 305 // 306 // If a name starts with "*", then the exported bit represents 307 // whether the pointed to type is exported. 308 type name struct { 309 bytes *byte 310 } 311 312 func (n name) data(off int, whySafe string) *byte { 313 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) 314 } 315 316 func (n name) isExported() bool { 317 return (*n.bytes)&(1<<0) != 0 318 } 319 320 func (n name) hasTag() bool { 321 return (*n.bytes)&(1<<1) != 0 322 } 323 324 func (n name) embedded() bool { 325 return (*n.bytes)&(1<<3) != 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() string { 342 if n.bytes == nil { 343 return "" 344 } 345 i, l := n.readVarint(1) 346 return unsafe.String(n.data(1+i, "non-empty string"), l) 347 } 348 349 func (n name) tag() string { 350 if !n.hasTag() { 351 return "" 352 } 353 i, l := n.readVarint(1) 354 i2, l2 := n.readVarint(1 + i + l) 355 return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2) 356 } 357 358 func (n name) pkgPath() string { 359 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 360 return "" 361 } 362 i, l := n.readVarint(1) 363 off := 1 + i + l 364 if n.hasTag() { 365 i2, l2 := n.readVarint(off) 366 off += i2 + l2 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 sqBrackets := 0 573 for i >= 0 && (s[i] != '.' || sqBrackets != 0) { 574 switch s[i] { 575 case ']': 576 sqBrackets++ 577 case '[': 578 sqBrackets-- 579 } 580 i-- 581 } 582 return s[i+1:] 583 } 584 585 func (t *rtype) chanDir() chanDir { 586 if t.Kind() != Chan { 587 panic("reflect: chanDir of non-chan type") 588 } 589 tt := (*chanType)(unsafe.Pointer(t)) 590 return chanDir(tt.dir) 591 } 592 593 func (t *rtype) Elem() Type { 594 switch t.Kind() { 595 case Array: 596 tt := (*arrayType)(unsafe.Pointer(t)) 597 return toType(tt.elem) 598 case Chan: 599 tt := (*chanType)(unsafe.Pointer(t)) 600 return toType(tt.elem) 601 case Map: 602 tt := (*mapType)(unsafe.Pointer(t)) 603 return toType(tt.elem) 604 case Ptr: 605 tt := (*ptrType)(unsafe.Pointer(t)) 606 return toType(tt.elem) 607 case Slice: 608 tt := (*sliceType)(unsafe.Pointer(t)) 609 return toType(tt.elem) 610 } 611 panic("reflect: Elem of invalid type") 612 } 613 614 func (t *rtype) In(i int) Type { 615 if t.Kind() != Func { 616 panic("reflect: In of non-func type") 617 } 618 tt := (*funcType)(unsafe.Pointer(t)) 619 return toType(tt.in()[i]) 620 } 621 622 func (t *rtype) Key() Type { 623 if t.Kind() != Map { 624 panic("reflect: Key of non-map type") 625 } 626 tt := (*mapType)(unsafe.Pointer(t)) 627 return toType(tt.key) 628 } 629 630 func (t *rtype) Len() int { 631 if t.Kind() != Array { 632 panic("reflect: Len of non-array type") 633 } 634 tt := (*arrayType)(unsafe.Pointer(t)) 635 return int(tt.len) 636 } 637 638 func (t *rtype) NumField() int { 639 if t.Kind() != Struct { 640 panic("reflect: NumField of non-struct type") 641 } 642 tt := (*structType)(unsafe.Pointer(t)) 643 return len(tt.fields) 644 } 645 646 func (t *rtype) NumIn() int { 647 if t.Kind() != Func { 648 panic("reflect: NumIn of non-func type") 649 } 650 tt := (*funcType)(unsafe.Pointer(t)) 651 return int(tt.inCount) 652 } 653 654 func (t *rtype) NumOut() int { 655 if t.Kind() != Func { 656 panic("reflect: NumOut of non-func type") 657 } 658 tt := (*funcType)(unsafe.Pointer(t)) 659 return len(tt.out()) 660 } 661 662 func (t *rtype) Out(i int) Type { 663 if t.Kind() != Func { 664 panic("reflect: Out of non-func type") 665 } 666 tt := (*funcType)(unsafe.Pointer(t)) 667 return toType(tt.out()[i]) 668 } 669 670 func (t *funcType) in() []*rtype { 671 uadd := unsafe.Sizeof(*t) 672 if t.tflag&tflagUncommon != 0 { 673 uadd += unsafe.Sizeof(uncommonType{}) 674 } 675 if t.inCount == 0 { 676 return nil 677 } 678 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 679 } 680 681 func (t *funcType) out() []*rtype { 682 uadd := unsafe.Sizeof(*t) 683 if t.tflag&tflagUncommon != 0 { 684 uadd += unsafe.Sizeof(uncommonType{}) 685 } 686 outCount := t.outCount & (1<<15 - 1) 687 if outCount == 0 { 688 return nil 689 } 690 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 691 } 692 693 // add returns p+x. 694 // 695 // The whySafe string is ignored, so that the function still inlines 696 // as efficiently as p+x, but all call sites should use the string to 697 // record why the addition is safe, which is to say why the addition 698 // does not cause x to advance to the very end of p's allocation 699 // and therefore point incorrectly at the next block in memory. 700 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 701 return unsafe.Pointer(uintptr(p) + x) 702 } 703 704 // NumMethod returns the number of interface methods in the type's method set. 705 func (t *interfaceType) NumMethod() int { return len(t.methods) } 706 707 // TypeOf returns the reflection Type that represents the dynamic type of i. 708 // If i is a nil interface value, TypeOf returns nil. 709 func TypeOf(i any) Type { 710 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 711 return toType(eface.typ) 712 } 713 714 func (t *rtype) Implements(u Type) bool { 715 if u == nil { 716 panic("reflect: nil type passed to Type.Implements") 717 } 718 if u.Kind() != Interface { 719 panic("reflect: non-interface type passed to Type.Implements") 720 } 721 return implements(u.(*rtype), t) 722 } 723 724 func (t *rtype) AssignableTo(u Type) bool { 725 if u == nil { 726 panic("reflect: nil type passed to Type.AssignableTo") 727 } 728 uu := u.(*rtype) 729 return directlyAssignable(uu, t) || implements(uu, t) 730 } 731 732 func (t *rtype) Comparable() bool { 733 return t.equal != nil 734 } 735 736 // implements reports whether the type V implements the interface type T. 737 func implements(T, V *rtype) bool { 738 if T.Kind() != Interface { 739 return false 740 } 741 t := (*interfaceType)(unsafe.Pointer(T)) 742 if len(t.methods) == 0 { 743 return true 744 } 745 746 // The same algorithm applies in both cases, but the 747 // method tables for an interface type and a concrete type 748 // are different, so the code is duplicated. 749 // In both cases the algorithm is a linear scan over the two 750 // lists - T's methods and V's methods - simultaneously. 751 // Since method tables are stored in a unique sorted order 752 // (alphabetical, with no duplicate method names), the scan 753 // through V's methods must hit a match for each of T's 754 // methods along the way, or else V does not implement T. 755 // This lets us run the scan in overall linear time instead of 756 // the quadratic time a naive search would require. 757 // See also ../runtime/iface.go. 758 if V.Kind() == Interface { 759 v := (*interfaceType)(unsafe.Pointer(V)) 760 i := 0 761 for j := 0; j < len(v.methods); j++ { 762 tm := &t.methods[i] 763 tmName := t.nameOff(tm.name) 764 vm := &v.methods[j] 765 vmName := V.nameOff(vm.name) 766 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) { 767 if !tmName.isExported() { 768 tmPkgPath := tmName.pkgPath() 769 if tmPkgPath == "" { 770 tmPkgPath = t.pkgPath.name() 771 } 772 vmPkgPath := vmName.pkgPath() 773 if vmPkgPath == "" { 774 vmPkgPath = v.pkgPath.name() 775 } 776 if tmPkgPath != vmPkgPath { 777 continue 778 } 779 } 780 if i++; i >= len(t.methods) { 781 return true 782 } 783 } 784 } 785 return false 786 } 787 788 v := V.uncommon() 789 if v == nil { 790 return false 791 } 792 i := 0 793 vmethods := v.methods() 794 for j := 0; j < int(v.mcount); j++ { 795 tm := &t.methods[i] 796 tmName := t.nameOff(tm.name) 797 vm := vmethods[j] 798 vmName := V.nameOff(vm.name) 799 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 800 if !tmName.isExported() { 801 tmPkgPath := tmName.pkgPath() 802 if tmPkgPath == "" { 803 tmPkgPath = t.pkgPath.name() 804 } 805 vmPkgPath := vmName.pkgPath() 806 if vmPkgPath == "" { 807 vmPkgPath = V.nameOff(v.pkgPath).name() 808 } 809 if tmPkgPath != vmPkgPath { 810 continue 811 } 812 } 813 if i++; i >= len(t.methods) { 814 return true 815 } 816 } 817 } 818 return false 819 } 820 821 // directlyAssignable reports whether a value x of type V can be directly 822 // assigned (using memmove) to a value of type T. 823 // https://golang.org/doc/go_spec.html#Assignability 824 // Ignoring the interface rules (implemented elsewhere) 825 // and the ideal constant rules (no ideal constants at run time). 826 func directlyAssignable(T, V *rtype) bool { 827 // x's type V is identical to T? 828 if T == V { 829 return true 830 } 831 832 // Otherwise at least one of T and V must not be defined 833 // and they must have the same kind. 834 if T.hasName() && V.hasName() || T.Kind() != V.Kind() { 835 return false 836 } 837 838 // x's type T and V must have identical underlying types. 839 return haveIdenticalUnderlyingType(T, V, true) 840 } 841 842 func haveIdenticalType(T, V Type, cmpTags bool) bool { 843 if cmpTags { 844 return T == V 845 } 846 847 if T.Name() != V.Name() || T.Kind() != V.Kind() { 848 return false 849 } 850 851 return haveIdenticalUnderlyingType(T.common(), V.common(), false) 852 } 853 854 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { 855 if T == V { 856 return true 857 } 858 859 kind := T.Kind() 860 if kind != V.Kind() { 861 return false 862 } 863 864 // Non-composite types of equal kind have same underlying type 865 // (the predefined instance of the type). 866 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 867 return true 868 } 869 870 // Composite types. 871 switch kind { 872 case Array: 873 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 874 875 case Chan: 876 // Special case: 877 // x is a bidirectional channel value, T is a channel type, 878 // and x's type V and T have identical element types. 879 if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) { 880 return true 881 } 882 883 // Otherwise continue test for identical underlying type. 884 return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 885 886 case Func: 887 t := (*funcType)(unsafe.Pointer(T)) 888 v := (*funcType)(unsafe.Pointer(V)) 889 if t.outCount != v.outCount || t.inCount != v.inCount { 890 return false 891 } 892 for i := 0; i < t.NumIn(); i++ { 893 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) { 894 return false 895 } 896 } 897 for i := 0; i < t.NumOut(); i++ { 898 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) { 899 return false 900 } 901 } 902 return true 903 904 case Interface: 905 t := (*interfaceType)(unsafe.Pointer(T)) 906 v := (*interfaceType)(unsafe.Pointer(V)) 907 if len(t.methods) == 0 && len(v.methods) == 0 { 908 return true 909 } 910 // Might have the same methods but still 911 // need a run time conversion. 912 return false 913 914 case Map: 915 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 916 917 case Ptr, Slice: 918 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 919 920 case Struct: 921 t := (*structType)(unsafe.Pointer(T)) 922 v := (*structType)(unsafe.Pointer(V)) 923 if len(t.fields) != len(v.fields) { 924 return false 925 } 926 if t.pkgPath.name() != v.pkgPath.name() { 927 return false 928 } 929 for i := range t.fields { 930 tf := &t.fields[i] 931 vf := &v.fields[i] 932 if tf.name.name() != vf.name.name() { 933 return false 934 } 935 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) { 936 return false 937 } 938 if cmpTags && tf.name.tag() != vf.name.tag() { 939 return false 940 } 941 if tf.offset != vf.offset { 942 return false 943 } 944 if tf.embedded() != vf.embedded() { 945 return false 946 } 947 } 948 return true 949 } 950 951 return false 952 } 953 954 type structTypeUncommon struct { 955 structType 956 u uncommonType 957 } 958 959 // toType converts from a *rtype to a Type that can be returned 960 // to the client of package reflect. In gc, the only concern is that 961 // a nil *rtype must be replaced by a nil Type, but in gccgo this 962 // function takes care of ensuring that multiple *rtype for the same 963 // type are coalesced into a single Type. 964 func toType(t *rtype) Type { 965 if t == nil { 966 return nil 967 } 968 return t 969 } 970 971 // ifaceIndir reports whether t is stored indirectly in an interface value. 972 func ifaceIndir(t *rtype) bool { 973 return t.kind&kindDirectIface == 0 974 }