github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/reflectlite/reflectlite1.18/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 reflect implements run-time reflection, allowing a program to 6 // manipulate objects with arbitrary types. The typical use is to take a value 7 // with static type interface{} and extract its dynamic type information by 8 // calling TypeOf, which returns a Type. 9 // 10 // A call to ValueOf returns a Value representing the run-time data. 11 // Zero takes a Type and returns a Value representing a zero value 12 // for that type. 13 // 14 // See "The Laws of Reflection" for an introduction to reflection in Go: 15 // https://golang.org/doc/articles/laws_of_reflection.html 16 package reflectlite 17 18 import ( 19 "github.com/eh-steve/goloader/reflectlite/internal/unsafeheader" 20 "strconv" 21 "sync" 22 "unsafe" 23 ) 24 25 // Type is the representation of a Go type. 26 // 27 // Not all methods apply to all kinds of types. Restrictions, 28 // if any, are noted in the documentation for each method. 29 // Use the Kind method to find out the kind of type before 30 // calling kind-specific methods. Calling a method 31 // inappropriate to the kind of type causes a run-time panic. 32 // 33 // Type values are comparable, such as with the == operator, 34 // so they can be used as map keys. 35 // Two Type values are equal if they represent identical types. 36 type Type interface { 37 38 // NumMethod returns the number of methods accessible using Method. 39 // 40 // For a non-interface type, it returns the number of exported methods. 41 // 42 // For an interface type, it returns the number of exported and unexported methods. 43 NumMethod() int 44 45 // Name returns the type's name within its package for a defined type. 46 // For other (non-defined) types it returns the empty string. 47 Name() string 48 49 // PkgPath returns a defined type's package path, that is, the import path 50 // that uniquely identifies the package, such as "encoding/base64". 51 // If the type was predeclared (string, error) or not defined (*T, struct{}, 52 // []int, or A where A is an alias for a non-defined type), the package path 53 // will be the empty string. 54 PkgPath() string 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 // Kind returns the specific kind of this type. 64 Kind() Kind 65 66 // ConvertibleTo reports whether a value of the type is convertible to type u. 67 // Even if ConvertibleTo returns true, the conversion may still panic. 68 // For example, a slice of type []T is convertible to *[N]T, 69 // but the conversion will panic if its length is less than N. 70 ConvertibleTo(u Type) bool 71 72 ConvertibleToWithInterface(u Type) bool 73 74 // ChanDir returns a channel type's direction. 75 // It panics if the type's Kind is not Chan. 76 ChanDir() ChanDir 77 78 // IsVariadic reports whether a function type's final input parameter 79 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 80 // implicit actual type []T. 81 // 82 // For concreteness, if t represents func(x int, y ... float64), then 83 // 84 // t.NumIn() == 2 85 // t.In(0) is the reflect.Type for "int" 86 // t.In(1) is the reflect.Type for "[]float64" 87 // t.IsVariadic() == true 88 // 89 // IsVariadic panics if the type's Kind is not Func. 90 IsVariadic() bool 91 92 // Elem returns a type's element type. 93 // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice. 94 Elem() Type 95 96 // Field returns a struct type's i'th field. 97 // It panics if the type's Kind is not Struct. 98 // It panics if i is not in the range [0, NumField()). 99 Field(i int) StructField 100 101 // In returns the type of a function type's i'th input parameter. 102 // It panics if the type's Kind is not Func. 103 // It panics if i is not in the range [0, NumIn()). 104 In(i int) Type 105 106 // Key returns a map type's key type. 107 // It panics if the type's Kind is not Map. 108 Key() Type 109 110 // Len returns an array type's length. 111 // It panics if the type's Kind is not Array. 112 Len() int 113 114 // NumField returns a struct type's field count. 115 // It panics if the type's Kind is not Struct. 116 NumField() int 117 118 // NumIn returns a function type's input parameter count. 119 // It panics if the type's Kind is not Func. 120 NumIn() int 121 122 // NumOut returns a function type's output parameter count. 123 // It panics if the type's Kind is not Func. 124 NumOut() int 125 126 // Out returns the type of a function type's i'th output parameter. 127 // It panics if the type's Kind is not Func. 128 // It panics if i is not in the range [0, NumOut()). 129 Out(i int) Type 130 131 common() *rtype 132 uncommon() *uncommonType 133 } 134 135 // BUG(rsc): FieldByName and related functions consider struct field names to be equal 136 // if the names are equal, even if they are unexported names originating 137 // in different packages. The practical effect of this is that the result of 138 // t.FieldByName("x") is not well defined if the struct type t contains 139 // multiple fields named x (embedded from different packages). 140 // FieldByName may return one of the fields named x or may report that there are none. 141 // See https://golang.org/issue/4876 for more details. 142 143 /* 144 * These data structures are known to the compiler (../cmd/compile/internal/reflectdata/reflect.go). 145 * A few are known to ../runtime/type.go to convey to debuggers. 146 * They are also known to ../runtime/type.go. 147 */ 148 149 // A Kind represents the specific kind of type that a Type represents. 150 // The zero Kind is not a valid kind. 151 type Kind uint 152 153 const ( 154 Invalid Kind = iota 155 Bool 156 Int 157 Int8 158 Int16 159 Int32 160 Int64 161 Uint 162 Uint8 163 Uint16 164 Uint32 165 Uint64 166 Uintptr 167 Float32 168 Float64 169 Complex64 170 Complex128 171 Array 172 Chan 173 Func 174 Interface 175 Map 176 Pointer 177 Slice 178 String 179 Struct 180 UnsafePointer 181 ) 182 183 // Ptr is the old name for the Pointer kind. 184 const Ptr = Pointer 185 186 // tflag is used by an rtype to signal what extra type information is 187 // available in the memory directly following the rtype value. 188 // 189 // tflag values must be kept in sync with copies in: 190 // 191 // cmd/compile/internal/reflectdata/reflect.go 192 // cmd/link/internal/ld/decodesym.go 193 // runtime/type.go 194 type tflag uint8 195 196 const ( 197 // tflagUncommon means that there is a pointer, *uncommonType, 198 // just beyond the outer type structure. 199 // 200 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 201 // then t has uncommonType data and it can be accessed as: 202 // 203 // type tUncommon struct { 204 // structType 205 // u uncommonType 206 // } 207 // u := &(*tUncommon)(unsafe.Pointer(t)).u 208 tflagUncommon tflag = 1 << 0 209 210 // tflagExtraStar means the name in the str field has an 211 // extraneous '*' prefix. This is because for most types T in 212 // a program, the type *T also exists and reusing the str data 213 // saves binary size. 214 tflagExtraStar tflag = 1 << 1 215 216 // tflagNamed means the type has a name. 217 tflagNamed tflag = 1 << 2 218 219 // tflagRegularMemory means that equal and hash functions can treat 220 // this type as a single region of t.size bytes. 221 tflagRegularMemory tflag = 1 << 3 222 ) 223 224 // rtype is the common implementation of most values. 225 // It is embedded in other struct types. 226 // 227 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 228 type rtype struct { 229 size uintptr 230 ptrdata uintptr // number of bytes in the type that can contain pointers 231 hash uint32 // hash of type; avoids computation in hash tables 232 tflag tflag // extra type information flags 233 align uint8 // alignment of variable with this type 234 fieldAlign uint8 // alignment of struct field with this type 235 kind uint8 // enumeration for C 236 // function for comparing objects of this type 237 // (ptr to object A, ptr to object B) -> ==? 238 equal func(unsafe.Pointer, unsafe.Pointer) bool 239 gcdata *byte // garbage collection data 240 str nameOff // string form 241 ptrToThis typeOff // type for pointer to this type, may be zero 242 } 243 244 type _typePair struct { 245 t1 *rtype 246 t2 *rtype 247 } 248 249 // Method on non-interface type 250 type method struct { 251 name nameOff // name of method 252 mtyp typeOff // method type (without receiver) 253 ifn textOff // fn used in interface call (one-word receiver) 254 tfn textOff // fn used for normal method call 255 } 256 257 // uncommonType is present only for defined types or types with methods 258 // (if T is a defined type, the uncommonTypes for T and *T have methods). 259 // Using a pointer to this struct reduces the overall size required 260 // to describe a non-defined type with no methods. 261 type uncommonType struct { 262 pkgPath nameOff // import path; empty for built-in types like int, string 263 mcount uint16 // number of methods 264 xcount uint16 // number of exported methods 265 moff uint32 // offset from this uncommontype to [mcount]method 266 _ uint32 // unused 267 } 268 269 // ChanDir represents a channel type's direction. 270 type ChanDir int 271 272 const ( 273 RecvDir ChanDir = 1 << iota // <-chan 274 SendDir // chan<- 275 BothDir = RecvDir | SendDir // chan 276 ) 277 278 // arrayType represents a fixed array type. 279 type arrayType struct { 280 rtype 281 elem *rtype // array element type 282 slice *rtype // slice type 283 len uintptr 284 } 285 286 // chanType represents a channel type. 287 type chanType struct { 288 rtype 289 elem *rtype // channel element type 290 dir uintptr // channel direction (ChanDir) 291 } 292 293 // funcType represents a function type. 294 // 295 // A *rtype for each in and out parameter is stored in an array that 296 // directly follows the funcType (and possibly its uncommonType). So 297 // a function type with one method, one input, and one output is: 298 // 299 // struct { 300 // funcType 301 // uncommonType 302 // [2]*rtype // [0] is in, [1] is out 303 // } 304 type funcType struct { 305 rtype 306 inCount uint16 307 outCount uint16 // top bit is set if last input parameter is ... 308 } 309 310 // imethod represents a method on an interface type 311 type imethod struct { 312 name nameOff // name of method 313 typ typeOff // .(*FuncType) underneath 314 } 315 316 // interfaceType represents an interface type. 317 type interfaceType struct { 318 rtype 319 pkgPath name // import path 320 methods []imethod // sorted by hash 321 } 322 323 // mapType represents a map type. 324 type mapType struct { 325 rtype 326 key *rtype // map key type 327 elem *rtype // map element (value) type 328 bucket *rtype // internal bucket structure 329 // function for hashing keys (ptr to key, seed) -> hash 330 hasher func(unsafe.Pointer, uintptr) uintptr 331 keysize uint8 // size of key slot 332 valuesize uint8 // size of value slot 333 bucketsize uint16 // size of bucket 334 flags uint32 335 } 336 337 // ptrType represents a pointer type. 338 type ptrType struct { 339 rtype 340 elem *rtype // pointer element (pointed at) type 341 } 342 343 // sliceType represents a slice type. 344 type sliceType struct { 345 rtype 346 elem *rtype // slice element type 347 } 348 349 // Struct field 350 type structField struct { 351 name name // name is always non-empty 352 typ *rtype // type of field 353 offsetEmbed uintptr // byte offset of field<<1 | isEmbedded 354 } 355 356 func (f *structField) offset() uintptr { 357 return f.offsetEmbed >> 1 358 } 359 360 func (f *structField) embedded() bool { 361 return f.offsetEmbed&1 != 0 362 } 363 364 // structType represents a struct type. 365 type structType struct { 366 rtype 367 pkgPath name 368 fields []structField // sorted by offset 369 } 370 371 // name is an encoded type name with optional extra data. 372 // 373 // The first byte is a bit field containing: 374 // 375 // 1<<0 the name is exported 376 // 1<<1 tag data follows the name 377 // 1<<2 pkgPath nameOff follows the name and tag 378 // 379 // Following that, there is a varint-encoded length of the name, 380 // followed by the name itself. 381 // 382 // If tag data is present, it also has a varint-encoded length 383 // followed by the tag itself. 384 // 385 // If the import path follows, then 4 bytes at the end of 386 // the data form a nameOff. The import path is only set for concrete 387 // methods that are defined in a different package than their type. 388 // 389 // If a name starts with "*", then the exported bit represents 390 // whether the pointed to type is exported. 391 // 392 // Note: this encoding must match here and in: 393 // cmd/compile/internal/reflectdata/reflect.go 394 // runtime/type.go 395 // internal/reflectlite/type.go 396 // cmd/link/internal/ld/decodesym.go 397 398 type name struct { 399 bytes *byte 400 } 401 402 func (n name) data(off int, whySafe string) *byte { 403 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) 404 } 405 406 func (n name) isExported() bool { 407 return (*n.bytes)&(1<<0) != 0 408 } 409 410 func (n name) hasTag() bool { 411 return (*n.bytes)&(1<<1) != 0 412 } 413 414 // readVarint parses a varint as encoded by encoding/binary. 415 // It returns the number of encoded bytes and the encoded value. 416 func (n name) readVarint(off int) (int, int) { 417 v := 0 418 for i := uint(0); ; i++ { 419 x := *n.data(off+int(i), "read varint") 420 v += int(x&0x7f) << (7 * i) 421 if x&0x80 == 0 { 422 return int(i + 1), v 423 } 424 } 425 } 426 427 // writeVarint writes n to buf in varint form. Returns the 428 // number of bytes written. n must be nonnegative. 429 // Writes at most 10 bytes. 430 func writeVarint(buf []byte, n int) int { 431 for i := 0; ; i++ { 432 b := byte(n & 0x7f) 433 n >>= 7 434 if n == 0 { 435 buf[i] = b 436 return i + 1 437 } 438 buf[i] = b | 0x80 439 } 440 } 441 442 func (n name) name() (s string) { 443 if n.bytes == nil { 444 return 445 } 446 i, l := n.readVarint(1) 447 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 448 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) 449 hdr.Len = l 450 return 451 } 452 453 func (n name) tag() (s string) { 454 if !n.hasTag() { 455 return "" 456 } 457 i, l := n.readVarint(1) 458 i2, l2 := n.readVarint(1 + i + l) 459 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 460 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string")) 461 hdr.Len = l2 462 return 463 } 464 465 func (n name) pkgPath() string { 466 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 467 return "" 468 } 469 i, l := n.readVarint(1) 470 off := 1 + i + l 471 if n.hasTag() { 472 i2, l2 := n.readVarint(off) 473 off += i2 + l2 474 } 475 var nameOff int32 476 // Note that this field may not be aligned in memory, 477 // so we cannot use a direct int32 assignment here. 478 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 479 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 480 return pkgPathName.name() 481 } 482 483 func newName(n, tag string, exported bool) name { 484 if len(n) >= 1<<29 { 485 panic("reflect.nameFrom: name too long: " + n[:1024] + "...") 486 } 487 if len(tag) >= 1<<29 { 488 panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...") 489 } 490 var nameLen [10]byte 491 var tagLen [10]byte 492 nameLenLen := writeVarint(nameLen[:], len(n)) 493 tagLenLen := writeVarint(tagLen[:], len(tag)) 494 495 var bits byte 496 l := 1 + nameLenLen + len(n) 497 if exported { 498 bits |= 1 << 0 499 } 500 if len(tag) > 0 { 501 l += tagLenLen + len(tag) 502 bits |= 1 << 1 503 } 504 505 b := make([]byte, l) 506 b[0] = bits 507 copy(b[1:], nameLen[:nameLenLen]) 508 copy(b[1+nameLenLen:], n) 509 if len(tag) > 0 { 510 tb := b[1+nameLenLen+len(n):] 511 copy(tb, tagLen[:tagLenLen]) 512 copy(tb[tagLenLen:], tag) 513 } 514 515 return name{bytes: &b[0]} 516 } 517 518 /* 519 * The compiler knows the exact layout of all the data structures above. 520 * The compiler does not know about the data structures and methods below. 521 */ 522 523 // Method represents a single method. 524 type Method struct { 525 // Name is the method name. 526 Name string 527 528 // PkgPath is the package path that qualifies a lower case (unexported) 529 // method name. It is empty for upper case (exported) method names. 530 // The combination of PkgPath and Name uniquely identifies a method 531 // in a method set. 532 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 533 PkgPath string 534 535 Type Type // method type 536 Func Value // func with receiver as first argument 537 Index int // index for Type.Method 538 } 539 540 // IsExported reports whether the method is exported. 541 func (m Method) IsExported() bool { 542 return m.PkgPath == "" 543 } 544 545 const ( 546 kindDirectIface = 1 << 5 547 kindGCProg = 1 << 6 // Type.gc points to GC program 548 kindMask = (1 << 5) - 1 549 ) 550 551 // String returns the name of k. 552 func (k Kind) String() string { 553 if int(k) < len(kindNames) { 554 return kindNames[k] 555 } 556 return "kind" + strconv.Itoa(int(k)) 557 } 558 559 var kindNames = []string{ 560 Invalid: "invalid", 561 Bool: "bool", 562 Int: "int", 563 Int8: "int8", 564 Int16: "int16", 565 Int32: "int32", 566 Int64: "int64", 567 Uint: "uint", 568 Uint8: "uint8", 569 Uint16: "uint16", 570 Uint32: "uint32", 571 Uint64: "uint64", 572 Uintptr: "uintptr", 573 Float32: "float32", 574 Float64: "float64", 575 Complex64: "complex64", 576 Complex128: "complex128", 577 Array: "array", 578 Chan: "chan", 579 Func: "func", 580 Interface: "interface", 581 Map: "map", 582 Pointer: "ptr", 583 Slice: "slice", 584 String: "string", 585 Struct: "struct", 586 UnsafePointer: "unsafe.Pointer", 587 } 588 589 func (t *uncommonType) methods() []method { 590 if t.mcount == 0 { 591 return nil 592 } 593 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 594 } 595 596 func (t *uncommonType) exportedMethods() []method { 597 if t.xcount == 0 { 598 return nil 599 } 600 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 601 } 602 603 // resolveNameOff resolves a name offset from a base pointer. 604 // The (*rtype).nameOff method is a convenience wrapper for this function. 605 // Implemented in the runtime package. 606 // 607 //go:linkname resolveNameOff reflect.resolveNameOff 608 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 609 610 // resolveTypeOff resolves an *rtype offset from a base type. 611 // The (*rtype).typeOff method is a convenience wrapper for this function. 612 // Implemented in the runtime package. 613 // 614 //go:linkname resolveTypeOff reflect.resolveTypeOff 615 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 616 617 // resolveTextOff resolves a function pointer offset from a base type. 618 // The (*rtype).textOff method is a convenience wrapper for this function. 619 // Implemented in the runtime package. 620 // 621 //go:linkname resolveTextOff reflect.resolveTextOff 622 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 623 624 //go:linkname addReflectOff reflect.addReflectOff 625 func addReflectOff(ptr unsafe.Pointer) int32 626 627 // resolveReflectName adds a name to the reflection lookup map in the runtime. 628 // It returns a new nameOff that can be used to refer to the pointer. 629 func resolveReflectName(n name) nameOff { 630 return nameOff(addReflectOff(unsafe.Pointer(n.bytes))) 631 } 632 633 type nameOff int32 // offset to a name 634 type typeOff int32 // offset to an *rtype 635 type textOff int32 // offset from top of text section 636 637 func (t *rtype) nameOff(off nameOff) name { 638 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 639 } 640 641 func (t *rtype) typeOff(off typeOff) *rtype { 642 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 643 } 644 645 func (t *rtype) textOff(off textOff) unsafe.Pointer { 646 return resolveTextOff(unsafe.Pointer(t), int32(off)) 647 } 648 649 func (t *rtype) uncommon() *uncommonType { 650 if t.tflag&tflagUncommon == 0 { 651 return nil 652 } 653 switch t.Kind() { 654 case Struct: 655 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 656 case Pointer: 657 type u struct { 658 ptrType 659 u uncommonType 660 } 661 return &(*u)(unsafe.Pointer(t)).u 662 case Func: 663 type u struct { 664 funcType 665 u uncommonType 666 } 667 return &(*u)(unsafe.Pointer(t)).u 668 case Slice: 669 type u struct { 670 sliceType 671 u uncommonType 672 } 673 return &(*u)(unsafe.Pointer(t)).u 674 case Array: 675 type u struct { 676 arrayType 677 u uncommonType 678 } 679 return &(*u)(unsafe.Pointer(t)).u 680 case Chan: 681 type u struct { 682 chanType 683 u uncommonType 684 } 685 return &(*u)(unsafe.Pointer(t)).u 686 case Map: 687 type u struct { 688 mapType 689 u uncommonType 690 } 691 return &(*u)(unsafe.Pointer(t)).u 692 case Interface: 693 type u struct { 694 interfaceType 695 u uncommonType 696 } 697 return &(*u)(unsafe.Pointer(t)).u 698 default: 699 type u struct { 700 rtype 701 u uncommonType 702 } 703 return &(*u)(unsafe.Pointer(t)).u 704 } 705 } 706 707 func (t *rtype) String() string { 708 s := t.nameOff(t.str).name() 709 if t.tflag&tflagExtraStar != 0 { 710 return s[1:] 711 } 712 return s 713 } 714 715 func (t *rtype) Size() uintptr { return t.size } 716 717 func (t *rtype) Bits() int { 718 if t == nil { 719 panic("reflect: Bits of nil Type") 720 } 721 k := t.Kind() 722 if k < Int || k > Complex128 { 723 panic("reflect: Bits of non-arithmetic Type " + t.String()) 724 } 725 return int(t.size) * 8 726 } 727 728 func (t *rtype) Align() int { return int(t.align) } 729 730 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) } 731 732 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 733 734 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 735 736 func (t *rtype) common() *rtype { return t } 737 738 func (t *rtype) exportedMethods() []method { 739 ut := t.uncommon() 740 if ut == nil { 741 return nil 742 } 743 return ut.exportedMethods() 744 } 745 746 func (t *rtype) NumMethod() int { 747 if t.Kind() == Interface { 748 tt := (*interfaceType)(unsafe.Pointer(t)) 749 return tt.NumMethod() 750 } 751 return len(t.exportedMethods()) 752 } 753 754 func (t *rtype) PkgPath() string { 755 if t.tflag&tflagNamed == 0 { 756 return "" 757 } 758 ut := t.uncommon() 759 if ut == nil { 760 return "" 761 } 762 return t.nameOff(ut.pkgPath).name() 763 } 764 765 func (t *rtype) hasName() bool { 766 return t.tflag&tflagNamed != 0 767 } 768 769 func (t *rtype) Name() string { 770 if !t.hasName() { 771 return "" 772 } 773 s := t.String() 774 i := len(s) - 1 775 sqBrackets := 0 776 for i >= 0 && (s[i] != '.' || sqBrackets != 0) { 777 switch s[i] { 778 case ']': 779 sqBrackets++ 780 case '[': 781 sqBrackets-- 782 } 783 i-- 784 } 785 return s[i+1:] 786 } 787 788 func (t *rtype) ChanDir() ChanDir { 789 if t.Kind() != Chan { 790 panic("reflect: ChanDir of non-chan type " + t.String()) 791 } 792 tt := (*chanType)(unsafe.Pointer(t)) 793 return ChanDir(tt.dir) 794 } 795 796 func (t *rtype) IsVariadic() bool { 797 if t.Kind() != Func { 798 panic("reflect: IsVariadic of non-func type " + t.String()) 799 } 800 tt := (*funcType)(unsafe.Pointer(t)) 801 return tt.outCount&(1<<15) != 0 802 } 803 804 func (t *rtype) Elem() Type { 805 switch t.Kind() { 806 case Array: 807 tt := (*arrayType)(unsafe.Pointer(t)) 808 return toType(tt.elem) 809 case Chan: 810 tt := (*chanType)(unsafe.Pointer(t)) 811 return toType(tt.elem) 812 case Map: 813 tt := (*mapType)(unsafe.Pointer(t)) 814 return toType(tt.elem) 815 case Pointer: 816 tt := (*ptrType)(unsafe.Pointer(t)) 817 return toType(tt.elem) 818 case Slice: 819 tt := (*sliceType)(unsafe.Pointer(t)) 820 return toType(tt.elem) 821 } 822 panic("reflect: Elem of invalid type " + t.String()) 823 } 824 825 func (t *rtype) Field(i int) StructField { 826 if t.Kind() != Struct { 827 panic("reflect: Field of non-struct type " + t.String()) 828 } 829 tt := (*structType)(unsafe.Pointer(t)) 830 return tt.Field(i) 831 } 832 833 func (t *rtype) FieldByIndex(index []int) StructField { 834 if t.Kind() != Struct { 835 panic("reflect: FieldByIndex of non-struct type " + t.String()) 836 } 837 tt := (*structType)(unsafe.Pointer(t)) 838 return tt.FieldByIndex(index) 839 } 840 841 func (t *rtype) FieldByName(name string) (StructField, bool) { 842 if t.Kind() != Struct { 843 panic("reflect: FieldByName of non-struct type " + t.String()) 844 } 845 tt := (*structType)(unsafe.Pointer(t)) 846 return tt.FieldByName(name) 847 } 848 849 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 850 if t.Kind() != Struct { 851 panic("reflect: FieldByNameFunc of non-struct type " + t.String()) 852 } 853 tt := (*structType)(unsafe.Pointer(t)) 854 return tt.FieldByNameFunc(match) 855 } 856 857 func (t *rtype) In(i int) Type { 858 if t.Kind() != Func { 859 panic("reflect: In of non-func type " + t.String()) 860 } 861 tt := (*funcType)(unsafe.Pointer(t)) 862 return toType(tt.in()[i]) 863 } 864 865 func (t *rtype) Key() Type { 866 if t.Kind() != Map { 867 panic("reflect: Key of non-map type " + t.String()) 868 } 869 tt := (*mapType)(unsafe.Pointer(t)) 870 return toType(tt.key) 871 } 872 873 func (t *rtype) Len() int { 874 if t.Kind() != Array { 875 panic("reflect: Len of non-array type " + t.String()) 876 } 877 tt := (*arrayType)(unsafe.Pointer(t)) 878 return int(tt.len) 879 } 880 881 func (t *rtype) NumField() int { 882 if t.Kind() != Struct { 883 panic("reflect: NumField of non-struct type " + t.String()) 884 } 885 tt := (*structType)(unsafe.Pointer(t)) 886 return len(tt.fields) 887 } 888 889 func (t *rtype) NumIn() int { 890 if t.Kind() != Func { 891 panic("reflect: NumIn of non-func type " + t.String()) 892 } 893 tt := (*funcType)(unsafe.Pointer(t)) 894 return int(tt.inCount) 895 } 896 897 func (t *rtype) NumOut() int { 898 if t.Kind() != Func { 899 panic("reflect: NumOut of non-func type " + t.String()) 900 } 901 tt := (*funcType)(unsafe.Pointer(t)) 902 return len(tt.out()) 903 } 904 905 func (t *rtype) Out(i int) Type { 906 if t.Kind() != Func { 907 panic("reflect: Out of non-func type " + t.String()) 908 } 909 tt := (*funcType)(unsafe.Pointer(t)) 910 return toType(tt.out()[i]) 911 } 912 913 func (t *funcType) in() []*rtype { 914 uadd := unsafe.Sizeof(*t) 915 if t.tflag&tflagUncommon != 0 { 916 uadd += unsafe.Sizeof(uncommonType{}) 917 } 918 if t.inCount == 0 { 919 return nil 920 } 921 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 922 } 923 924 func (t *funcType) out() []*rtype { 925 uadd := unsafe.Sizeof(*t) 926 if t.tflag&tflagUncommon != 0 { 927 uadd += unsafe.Sizeof(uncommonType{}) 928 } 929 outCount := t.outCount & (1<<15 - 1) 930 if outCount == 0 { 931 return nil 932 } 933 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 934 } 935 936 // add returns p+x. 937 // 938 // The whySafe string is ignored, so that the function still inlines 939 // as efficiently as p+x, but all call sites should use the string to 940 // record why the addition is safe, which is to say why the addition 941 // does not cause x to advance to the very end of p's allocation 942 // and therefore point incorrectly at the next block in memory. 943 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 944 return unsafe.Pointer(uintptr(p) + x) 945 } 946 947 func (d ChanDir) String() string { 948 switch d { 949 case SendDir: 950 return "chan<-" 951 case RecvDir: 952 return "<-chan" 953 case BothDir: 954 return "chan" 955 } 956 return "ChanDir" + strconv.Itoa(int(d)) 957 } 958 959 // Method returns the i'th method in the type's method set. 960 func (t *interfaceType) Method(i int) (m Method) { 961 if i < 0 || i >= len(t.methods) { 962 return 963 } 964 p := &t.methods[i] 965 pname := t.nameOff(p.name) 966 m.Name = pname.name() 967 if !pname.isExported() { 968 m.PkgPath = pname.pkgPath() 969 if m.PkgPath == "" { 970 m.PkgPath = t.pkgPath.name() 971 } 972 } 973 m.Type = toType(t.typeOff(p.typ)) 974 m.Index = i 975 return 976 } 977 978 // NumMethod returns the number of interface methods in the type's method set. 979 func (t *interfaceType) NumMethod() int { return len(t.methods) } 980 981 // MethodByName method with the given name in the type's method set. 982 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) { 983 if t == nil { 984 return 985 } 986 var p *imethod 987 for i := range t.methods { 988 p = &t.methods[i] 989 if t.nameOff(p.name).name() == name { 990 return t.Method(i), true 991 } 992 } 993 return 994 } 995 996 // A StructField describes a single field in a struct. 997 type StructField struct { 998 // Name is the field name. 999 Name string 1000 1001 // PkgPath is the package path that qualifies a lower case (unexported) 1002 // field name. It is empty for upper case (exported) field names. 1003 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 1004 PkgPath string 1005 1006 Type Type // field type 1007 Tag StructTag // field tag string 1008 Offset uintptr // offset within struct, in bytes 1009 Index []int // index sequence for Type.FieldByIndex 1010 Anonymous bool // is an embedded field 1011 } 1012 1013 // IsExported reports whether the field is exported. 1014 func (f StructField) IsExported() bool { 1015 return f.PkgPath == "" 1016 } 1017 1018 // A StructTag is the tag string in a struct field. 1019 // 1020 // By convention, tag strings are a concatenation of 1021 // optionally space-separated key:"value" pairs. 1022 // Each key is a non-empty string consisting of non-control 1023 // characters other than space (U+0020 ' '), quote (U+0022 '"'), 1024 // and colon (U+003A ':'). Each value is quoted using U+0022 '"' 1025 // characters and Go string literal syntax. 1026 type StructTag string 1027 1028 // Get returns the value associated with key in the tag string. 1029 // If there is no such key in the tag, Get returns the empty string. 1030 // If the tag does not have the conventional format, the value 1031 // returned by Get is unspecified. To determine whether a tag is 1032 // explicitly set to the empty string, use Lookup. 1033 func (tag StructTag) Get(key string) string { 1034 v, _ := tag.Lookup(key) 1035 return v 1036 } 1037 1038 // Lookup returns the value associated with key in the tag string. 1039 // If the key is present in the tag the value (which may be empty) 1040 // is returned. Otherwise the returned value will be the empty string. 1041 // The ok return value reports whether the value was explicitly set in 1042 // the tag string. If the tag does not have the conventional format, 1043 // the value returned by Lookup is unspecified. 1044 func (tag StructTag) Lookup(key string) (value string, ok bool) { 1045 // When modifying this code, also update the validateStructTag code 1046 // in cmd/vet/structtag.go. 1047 1048 for tag != "" { 1049 // Skip leading space. 1050 i := 0 1051 for i < len(tag) && tag[i] == ' ' { 1052 i++ 1053 } 1054 tag = tag[i:] 1055 if tag == "" { 1056 break 1057 } 1058 1059 // Scan to colon. A space, a quote or a control character is a syntax error. 1060 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just 1061 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters 1062 // as it is simpler to inspect the tag's bytes than the tag's runes. 1063 i = 0 1064 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { 1065 i++ 1066 } 1067 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 1068 break 1069 } 1070 name := string(tag[:i]) 1071 tag = tag[i+1:] 1072 1073 // Scan quoted string to find value. 1074 i = 1 1075 for i < len(tag) && tag[i] != '"' { 1076 if tag[i] == '\\' { 1077 i++ 1078 } 1079 i++ 1080 } 1081 if i >= len(tag) { 1082 break 1083 } 1084 qvalue := string(tag[:i+1]) 1085 tag = tag[i+1:] 1086 1087 if key == name { 1088 value, err := strconv.Unquote(qvalue) 1089 if err != nil { 1090 break 1091 } 1092 return value, true 1093 } 1094 } 1095 return "", false 1096 } 1097 1098 // Field returns the i'th struct field. 1099 func (t *structType) Field(i int) (f StructField) { 1100 if i < 0 || i >= len(t.fields) { 1101 panic("reflect: Field index out of bounds") 1102 } 1103 p := &t.fields[i] 1104 f.Type = toType(p.typ) 1105 f.Name = p.name.name() 1106 f.Anonymous = p.embedded() 1107 if !p.name.isExported() { 1108 f.PkgPath = t.pkgPath.name() 1109 } 1110 if tag := p.name.tag(); tag != "" { 1111 f.Tag = StructTag(tag) 1112 } 1113 f.Offset = p.offset() 1114 1115 // NOTE(rsc): This is the only allocation in the interface 1116 // presented by a reflect.Type. It would be nice to avoid, 1117 // at least in the common cases, but we need to make sure 1118 // that misbehaving clients of reflect cannot affect other 1119 // uses of reflect. One possibility is CL 5371098, but we 1120 // postponed that ugliness until there is a demonstrated 1121 // need for the performance. This is issue 2320. 1122 f.Index = []int{i} 1123 return 1124 } 1125 1126 // TODO(gri): Should there be an error/bool indicator if the index 1127 // is wrong for FieldByIndex? 1128 1129 // FieldByIndex returns the nested field corresponding to index. 1130 func (t *structType) FieldByIndex(index []int) (f StructField) { 1131 f.Type = toType(&t.rtype) 1132 for i, x := range index { 1133 if i > 0 { 1134 ft := f.Type 1135 if ft.Kind() == Pointer && ft.Elem().Kind() == Struct { 1136 ft = ft.Elem() 1137 } 1138 f.Type = ft 1139 } 1140 f = f.Type.Field(x) 1141 } 1142 return 1143 } 1144 1145 // A fieldScan represents an item on the fieldByNameFunc scan work list. 1146 type fieldScan struct { 1147 typ *structType 1148 index []int 1149 } 1150 1151 // FieldByNameFunc returns the struct field with a name that satisfies the 1152 // match function and a boolean to indicate if the field was found. 1153 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) { 1154 // This uses the same condition that the Go language does: there must be a unique instance 1155 // of the match at a given depth level. If there are multiple instances of a match at the 1156 // same depth, they annihilate each other and inhibit interface{} possible match at a lower level. 1157 // The algorithm is breadth first search, one depth level at a time. 1158 1159 // The current and next slices are work queues: 1160 // current lists the fields to visit on this depth level, 1161 // and next lists the fields on the next lower level. 1162 current := []fieldScan{} 1163 next := []fieldScan{{typ: t}} 1164 1165 // nextCount records the number of times an embedded type has been 1166 // encountered and considered for queueing in the 'next' slice. 1167 // We only queue the first one, but we increment the count on each. 1168 // If a struct type T can be reached more than once at a given depth level, 1169 // then it annihilates itself and need not be considered at all when we 1170 // process that next depth level. 1171 var nextCount map[*structType]int 1172 1173 // visited records the structs that have been considered already. 1174 // Embedded pointer fields can create cycles in the graph of 1175 // reachable embedded types; visited avoids following those cycles. 1176 // It also avoids duplicated effort: if we didn't find the field in an 1177 // embedded type T at level 2, we won't find it in one at level 4 either. 1178 visited := map[*structType]bool{} 1179 1180 for len(next) > 0 { 1181 current, next = next, current[:0] 1182 count := nextCount 1183 nextCount = nil 1184 1185 // Process all the fields at this depth, now listed in 'current'. 1186 // The loop queues embedded fields found in 'next', for processing during the next 1187 // iteration. The multiplicity of the 'current' field counts is recorded 1188 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. 1189 for _, scan := range current { 1190 t := scan.typ 1191 if visited[t] { 1192 // We've looked through this type before, at a higher level. 1193 // That higher level would shadow the lower level we're now at, 1194 // so this one can't be useful to us. Ignore it. 1195 continue 1196 } 1197 visited[t] = true 1198 for i := range t.fields { 1199 f := &t.fields[i] 1200 // Find name and (for embedded field) type for field f. 1201 fname := f.name.name() 1202 var ntyp *rtype 1203 if f.embedded() { 1204 // Embedded field of type T or *T. 1205 ntyp = f.typ 1206 if ntyp.Kind() == Pointer { 1207 ntyp = ntyp.Elem().common() 1208 } 1209 } 1210 1211 // Does it match? 1212 if match(fname) { 1213 // Potential match 1214 if count[t] > 1 || ok { 1215 // Name appeared multiple times at this level: annihilate. 1216 return StructField{}, false 1217 } 1218 result = t.Field(i) 1219 result.Index = nil 1220 result.Index = append(result.Index, scan.index...) 1221 result.Index = append(result.Index, i) 1222 ok = true 1223 continue 1224 } 1225 1226 // Queue embedded struct fields for processing with next level, 1227 // but only if we haven't seen a match yet at this level and only 1228 // if the embedded types haven't already been queued. 1229 if ok || ntyp == nil || ntyp.Kind() != Struct { 1230 continue 1231 } 1232 styp := (*structType)(unsafe.Pointer(ntyp)) 1233 if nextCount[styp] > 0 { 1234 nextCount[styp] = 2 // exact multiple doesn't matter 1235 continue 1236 } 1237 if nextCount == nil { 1238 nextCount = map[*structType]int{} 1239 } 1240 nextCount[styp] = 1 1241 if count[t] > 1 { 1242 nextCount[styp] = 2 // exact multiple doesn't matter 1243 } 1244 var index []int 1245 index = append(index, scan.index...) 1246 index = append(index, i) 1247 next = append(next, fieldScan{styp, index}) 1248 } 1249 } 1250 if ok { 1251 break 1252 } 1253 } 1254 return 1255 } 1256 1257 // FieldByName returns the struct field with the given name 1258 // and a boolean to indicate if the field was found. 1259 func (t *structType) FieldByName(name string) (f StructField, present bool) { 1260 // Quick check for top-level name, or struct without embedded fields. 1261 hasEmbeds := false 1262 if name != "" { 1263 for i := range t.fields { 1264 tf := &t.fields[i] 1265 if tf.name.name() == name { 1266 return t.Field(i), true 1267 } 1268 if tf.embedded() { 1269 hasEmbeds = true 1270 } 1271 } 1272 } 1273 if !hasEmbeds { 1274 return 1275 } 1276 return t.FieldByNameFunc(func(s string) bool { return s == name }) 1277 } 1278 1279 // TypeOf returns the reflection Type that represents the dynamic type of i. 1280 // If i is a nil interface value, TypeOf returns nil. 1281 func TypeOf(i interface{}) Type { 1282 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1283 return toType(eface.typ) 1284 } 1285 1286 // ptrMap is the cache for PointerTo. 1287 var ptrMap sync.Map // map[*rtype]*ptrType 1288 1289 func (t *rtype) ptrTo() *rtype { 1290 if t.ptrToThis != 0 { 1291 return t.typeOff(t.ptrToThis) 1292 } 1293 1294 // Check the cache. 1295 if pi, ok := ptrMap.Load(t); ok { 1296 return &pi.(*ptrType).rtype 1297 } 1298 1299 // Look in known types. 1300 s := "*" + t.String() 1301 for _, tt := range typesByString(s) { 1302 p := (*ptrType)(unsafe.Pointer(tt)) 1303 if p.elem != t { 1304 continue 1305 } 1306 pi, _ := ptrMap.LoadOrStore(t, p) 1307 return &pi.(*ptrType).rtype 1308 } 1309 1310 // Create a new ptrType starting with the description 1311 // of an *unsafe.Pointer. 1312 var iptr interface{} = (*unsafe.Pointer)(nil) 1313 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 1314 pp := *prototype 1315 1316 pp.str = resolveReflectName(newName(s, "", false)) 1317 pp.ptrToThis = 0 1318 1319 // For the type structures linked into the binary, the 1320 // compiler provides a good hash of the string. 1321 // Create a good hash for the new string by using 1322 // the FNV-1 hash's mixing function to combine the 1323 // old hash and the new "*". 1324 pp.hash = fnv1(t.hash, '*') 1325 1326 pp.elem = t 1327 1328 pi, _ := ptrMap.LoadOrStore(t, &pp) 1329 return &pi.(*ptrType).rtype 1330 } 1331 1332 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 1333 func fnv1(x uint32, list ...byte) uint32 { 1334 for _, b := range list { 1335 x = x*16777619 ^ uint32(b) 1336 } 1337 return x 1338 } 1339 1340 func (t *rtype) ConvertibleTo(u Type) bool { 1341 if u == nil { 1342 panic("reflect: nil type passed to Type.ConvertibleTo") 1343 } 1344 uu := u.(*rtype) 1345 1346 seen := map[_typePair]struct{}{} 1347 return convertOp(uu, t, false, seen) != nil 1348 } 1349 1350 func (t *rtype) ConvertibleToWithInterface(u Type) bool { 1351 if u == nil { 1352 panic("reflect: nil type passed to Type.ConvertibleTo") 1353 } 1354 uu := u.(*rtype) 1355 1356 seen := map[_typePair]struct{}{} 1357 return convertOp(uu, t, true, seen) != nil 1358 } 1359 1360 func (t *rtype) Comparable() bool { 1361 return t.equal != nil 1362 } 1363 1364 // implements reports whether the type V implements the interface type T. 1365 func implements(T, V *rtype, seen map[_typePair]struct{}) bool { 1366 if T.Kind() != Interface { 1367 return false 1368 } 1369 t := (*interfaceType)(unsafe.Pointer(T)) 1370 if len(t.methods) == 0 { 1371 return true 1372 } 1373 1374 // The same algorithm applies in both cases, but the 1375 // method tables for an interface type and a concrete type 1376 // are different, so the code is duplicated. 1377 // In both cases the algorithm is a linear scan over the two 1378 // lists - T's methods and V's methods - simultaneously. 1379 // Since method tables are stored in a unique sorted order 1380 // (alphabetical, with no duplicate method names), the scan 1381 // through V's methods must hit a match for each of T's 1382 // methods along the way, or else V does not implement T. 1383 // This lets us run the scan in overall linear time instead of 1384 // the quadratic time a naive search would require. 1385 // See also ../runtime/iface.go. 1386 if V.Kind() == Interface { 1387 v := (*interfaceType)(unsafe.Pointer(V)) 1388 i := 0 1389 for j := 0; j < len(v.methods); j++ { 1390 tm := &t.methods[i] 1391 tmName := t.nameOff(tm.name) 1392 vm := &v.methods[j] 1393 vmName := V.nameOff(vm.name) 1394 if vmName.name() == tmName.name() && haveIdenticalUnderlyingType(V.typeOff(vm.typ), t.typeOff(tm.typ), false, true, seen) { 1395 if !tmName.isExported() { 1396 tmPkgPath := tmName.pkgPath() 1397 if tmPkgPath == "" { 1398 tmPkgPath = t.pkgPath.name() 1399 } 1400 vmPkgPath := vmName.pkgPath() 1401 if vmPkgPath == "" { 1402 vmPkgPath = v.pkgPath.name() 1403 } 1404 if tmPkgPath != vmPkgPath { 1405 continue 1406 } 1407 } 1408 if i++; i >= len(t.methods) { 1409 return true 1410 } 1411 } 1412 } 1413 return false 1414 } 1415 1416 v := V.uncommon() 1417 if v == nil { 1418 return false 1419 } 1420 i := 0 1421 vmethods := v.methods() 1422 for j := 0; j < int(v.mcount); j++ { 1423 tm := &t.methods[i] 1424 tmName := t.nameOff(tm.name) 1425 vm := vmethods[j] 1426 vmName := V.nameOff(vm.name) 1427 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 1428 if !tmName.isExported() { 1429 tmPkgPath := tmName.pkgPath() 1430 if tmPkgPath == "" { 1431 tmPkgPath = t.pkgPath.name() 1432 } 1433 vmPkgPath := vmName.pkgPath() 1434 if vmPkgPath == "" { 1435 vmPkgPath = V.nameOff(v.pkgPath).name() 1436 } 1437 if tmPkgPath != vmPkgPath { 1438 continue 1439 } 1440 } 1441 if i++; i >= len(t.methods) { 1442 return true 1443 } 1444 } 1445 } 1446 return false 1447 } 1448 1449 // specialChannelAssignability reports whether a value x of channel type V 1450 // can be directly assigned (using memmove) to another channel type T. 1451 // https://golang.org/doc/go_spec.html#Assignability 1452 // T and V must be both of Chan kind. 1453 func specialChannelAssignability(T, V *rtype, seen map[_typePair]struct{}) bool { 1454 // Special case: 1455 // x is a bidirectional channel value, T is a channel type, 1456 // x's type V and T have identical element types, 1457 // and at least one of V or T is not a defined type. 1458 return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true, true, seen) 1459 } 1460 1461 // directlyAssignable reports whether a value x of type V can be directly 1462 // assigned (using memmove) to a value of type T. 1463 // https://golang.org/doc/go_spec.html#Assignability 1464 // Ignoring the interface rules (implemented elsewhere) 1465 // and the ideal constant rules (no ideal constants at run time). 1466 func directlyAssignable(T, V *rtype, seen map[_typePair]struct{}) bool { 1467 // x's type V is identical to T? 1468 if T == V { 1469 return true 1470 } 1471 1472 // Otherwise at least one of T and V must not be defined 1473 // and they must have the same kind. 1474 if T.Kind() != V.Kind() { 1475 return false 1476 } 1477 1478 if T.Kind() == Chan && specialChannelAssignability(T, V, seen) { 1479 return true 1480 } 1481 1482 // x's type T and V must have identical underlying types. 1483 return haveIdenticalUnderlyingType(T, V, false, false, seen) 1484 } 1485 1486 // typelinks is implemented in package runtime. 1487 // It returns a slice of the sections in each module, 1488 // and a slice of *rtype offsets in each module. 1489 // 1490 // The types in each module are sorted by string. That is, the first 1491 // two linked types of the first module are: 1492 // 1493 // d0 := sections[0] 1494 // t1 := (*rtype)(add(d0, offset[0][0])) 1495 // t2 := (*rtype)(add(d0, offset[0][1])) 1496 // 1497 // and 1498 // 1499 // t1.String() < t2.String() 1500 // 1501 // Note that strings are not unique identifiers for types: 1502 // there can be more than one with a given string. 1503 // Only types we might want to look up are included: 1504 // pointers, channels, maps, slices, and arrays. 1505 // 1506 //go:linkname typelinks reflect.typelinks 1507 func typelinks() (sections []unsafe.Pointer, offset [][]int32) 1508 1509 func rtypeOff(section unsafe.Pointer, off int32) *rtype { 1510 return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0")) 1511 } 1512 1513 // typesByString returns the subslice of typelinks() whose elements have 1514 // the given string representation. 1515 // It may be empty (no known types with that string) or may have 1516 // multiple elements (multiple types with that string). 1517 func typesByString(s string) []*rtype { 1518 sections, offset := typelinks() 1519 var ret []*rtype 1520 1521 for offsI, offs := range offset { 1522 section := sections[offsI] 1523 1524 // We are looking for the first index i where the string becomes >= s. 1525 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s). 1526 i, j := 0, len(offs) 1527 for i < j { 1528 h := i + (j-i)>>1 // avoid overflow when computing h 1529 // i ≤ h < j 1530 if !(rtypeOff(section, offs[h]).String() >= s) { 1531 i = h + 1 // preserves f(i-1) == false 1532 } else { 1533 j = h // preserves f(j) == true 1534 } 1535 } 1536 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 1537 1538 // Having found the first, linear scan forward to find the last. 1539 // We could do a second binary search, but the caller is going 1540 // to do a linear scan anyway. 1541 for j := i; j < len(offs); j++ { 1542 typ := rtypeOff(section, offs[j]) 1543 if typ.String() != s { 1544 break 1545 } 1546 ret = append(ret, typ) 1547 } 1548 } 1549 return ret 1550 } 1551 1552 // Make sure these routines stay in sync with ../../runtime/map.go! 1553 // These types exist only for GC, so we only fill out GC relevant info. 1554 // Currently, that's just size and the GC program. We also fill in string 1555 // for possible debugging use. 1556 const ( 1557 maxValSize uintptr = 128 1558 ) 1559 1560 func (t *rtype) gcSlice(begin, end uintptr) []byte { 1561 return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end] 1562 } 1563 1564 type structTypeUncommon struct { 1565 structType 1566 u uncommonType 1567 } 1568 1569 // toType converts from a *rtype to a Type that can be returned 1570 // to the client of package reflect. In gc, the only concern is that 1571 // a nil *rtype must be replaced by a nil Type, but in gccgo this 1572 // function takes care of ensuring that multiple *rtype for the same 1573 // type are coalesced into a single Type. 1574 func toType(t *rtype) Type { 1575 if t == nil { 1576 return nil 1577 } 1578 return t 1579 } 1580 1581 // ifaceIndir reports whether t is stored indirectly in an interface value. 1582 func ifaceIndir(t *rtype) bool { 1583 return t.kind&kindDirectIface == 0 1584 }