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