github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/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 "unsafe" 11 12 "github.com/hxx258456/ccgo/internal/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/reflectdata/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/reflectdata/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) hasTag() bool { 326 return (*n.bytes)&(1<<1) != 0 327 } 328 329 // readVarint parses a varint as encoded by encoding/binary. 330 // It returns the number of encoded bytes and the encoded value. 331 func (n name) readVarint(off int) (int, int) { 332 v := 0 333 for i := 0; ; i++ { 334 x := *n.data(off+i, "read varint") 335 v += int(x&0x7f) << (7 * i) 336 if x&0x80 == 0 { 337 return i + 1, v 338 } 339 } 340 } 341 342 func (n name) name() (s string) { 343 if n.bytes == nil { 344 return 345 } 346 i, l := n.readVarint(1) 347 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 348 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) 349 hdr.Len = l 350 return 351 } 352 353 func (n name) tag() (s string) { 354 if !n.hasTag() { 355 return "" 356 } 357 i, l := n.readVarint(1) 358 i2, l2 := n.readVarint(1 + i + l) 359 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 360 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string")) 361 hdr.Len = l2 362 return 363 } 364 365 func (n name) pkgPath() string { 366 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 367 return "" 368 } 369 i, l := n.readVarint(1) 370 off := 1 + i + l 371 if n.hasTag() { 372 i2, l2 := n.readVarint(off) 373 off += i2 + l2 374 } 375 var nameOff int32 376 // Note that this field may not be aligned in memory, 377 // so we cannot use a direct int32 assignment here. 378 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 379 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 380 return pkgPathName.name() 381 } 382 383 /* 384 * The compiler knows the exact layout of all the data structures above. 385 * The compiler does not know about the data structures and methods below. 386 */ 387 388 const ( 389 kindDirectIface = 1 << 5 390 kindGCProg = 1 << 6 // Type.gc points to GC program 391 kindMask = (1 << 5) - 1 392 ) 393 394 // String returns the name of k. 395 func (k Kind) String() string { 396 if int(k) < len(kindNames) { 397 return kindNames[k] 398 } 399 return kindNames[0] 400 } 401 402 var kindNames = []string{ 403 Invalid: "invalid", 404 Bool: "bool", 405 Int: "int", 406 Int8: "int8", 407 Int16: "int16", 408 Int32: "int32", 409 Int64: "int64", 410 Uint: "uint", 411 Uint8: "uint8", 412 Uint16: "uint16", 413 Uint32: "uint32", 414 Uint64: "uint64", 415 Uintptr: "uintptr", 416 Float32: "float32", 417 Float64: "float64", 418 Complex64: "complex64", 419 Complex128: "complex128", 420 Array: "array", 421 Chan: "chan", 422 Func: "func", 423 Interface: "interface", 424 Map: "map", 425 Ptr: "ptr", 426 Slice: "slice", 427 String: "string", 428 Struct: "struct", 429 UnsafePointer: "unsafe.Pointer", 430 } 431 432 func (t *uncommonType) methods() []method { 433 if t.mcount == 0 { 434 return nil 435 } 436 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 437 } 438 439 func (t *uncommonType) exportedMethods() []method { 440 if t.xcount == 0 { 441 return nil 442 } 443 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 444 } 445 446 // resolveNameOff resolves a name offset from a base pointer. 447 // The (*rtype).nameOff method is a convenience wrapper for this function. 448 // Implemented in the runtime package. 449 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 450 451 // resolveTypeOff resolves an *rtype offset from a base type. 452 // The (*rtype).typeOff method is a convenience wrapper for this function. 453 // Implemented in the runtime package. 454 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 455 456 type nameOff int32 // offset to a name 457 type typeOff int32 // offset to an *rtype 458 type textOff int32 // offset from top of text section 459 460 func (t *rtype) nameOff(off nameOff) name { 461 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 462 } 463 464 func (t *rtype) typeOff(off typeOff) *rtype { 465 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 466 } 467 468 func (t *rtype) uncommon() *uncommonType { 469 if t.tflag&tflagUncommon == 0 { 470 return nil 471 } 472 switch t.Kind() { 473 case Struct: 474 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 475 case Ptr: 476 type u struct { 477 ptrType 478 u uncommonType 479 } 480 return &(*u)(unsafe.Pointer(t)).u 481 case Func: 482 type u struct { 483 funcType 484 u uncommonType 485 } 486 return &(*u)(unsafe.Pointer(t)).u 487 case Slice: 488 type u struct { 489 sliceType 490 u uncommonType 491 } 492 return &(*u)(unsafe.Pointer(t)).u 493 case Array: 494 type u struct { 495 arrayType 496 u uncommonType 497 } 498 return &(*u)(unsafe.Pointer(t)).u 499 case Chan: 500 type u struct { 501 chanType 502 u uncommonType 503 } 504 return &(*u)(unsafe.Pointer(t)).u 505 case Map: 506 type u struct { 507 mapType 508 u uncommonType 509 } 510 return &(*u)(unsafe.Pointer(t)).u 511 case Interface: 512 type u struct { 513 interfaceType 514 u uncommonType 515 } 516 return &(*u)(unsafe.Pointer(t)).u 517 default: 518 type u struct { 519 rtype 520 u uncommonType 521 } 522 return &(*u)(unsafe.Pointer(t)).u 523 } 524 } 525 526 func (t *rtype) String() string { 527 s := t.nameOff(t.str).name() 528 if t.tflag&tflagExtraStar != 0 { 529 return s[1:] 530 } 531 return s 532 } 533 534 func (t *rtype) Size() uintptr { return t.size } 535 536 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 537 538 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 539 540 func (t *rtype) common() *rtype { return t } 541 542 func (t *rtype) exportedMethods() []method { 543 ut := t.uncommon() 544 if ut == nil { 545 return nil 546 } 547 return ut.exportedMethods() 548 } 549 550 func (t *rtype) NumMethod() int { 551 if t.Kind() == Interface { 552 tt := (*interfaceType)(unsafe.Pointer(t)) 553 return tt.NumMethod() 554 } 555 return len(t.exportedMethods()) 556 } 557 558 func (t *rtype) PkgPath() string { 559 if t.tflag&tflagNamed == 0 { 560 return "" 561 } 562 ut := t.uncommon() 563 if ut == nil { 564 return "" 565 } 566 return t.nameOff(ut.pkgPath).name() 567 } 568 569 func (t *rtype) hasName() bool { 570 return t.tflag&tflagNamed != 0 571 } 572 573 func (t *rtype) Name() string { 574 if !t.hasName() { 575 return "" 576 } 577 s := t.String() 578 i := len(s) - 1 579 for i >= 0 && s[i] != '.' { 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 interface{}) 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.offsetEmbed != vf.offsetEmbed { 942 return false 943 } 944 } 945 return true 946 } 947 948 return false 949 } 950 951 type structTypeUncommon struct { 952 structType 953 u uncommonType 954 } 955 956 // toType converts from a *rtype to a Type that can be returned 957 // to the client of package reflect. In gc, the only concern is that 958 // a nil *rtype must be replaced by a nil Type, but in gccgo this 959 // function takes care of ensuring that multiple *rtype for the same 960 // type are coalesced into a single Type. 961 func toType(t *rtype) Type { 962 if t == nil { 963 return nil 964 } 965 return t 966 } 967 968 // ifaceIndir reports whether t is stored indirectly in an interface value. 969 func ifaceIndir(t *rtype) bool { 970 return t.kind&kindDirectIface == 0 971 }