github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/reflectlite/reflectlite1.19/type.go (about) 1 package reflectlite 2 3 import ( 4 "github.com/eh-steve/goloader/reflectlite/internal/unsafeheader" 5 "strconv" 6 "sync" 7 "unsafe" 8 ) 9 10 // Type is the representation of a Go type. 11 // 12 // Not all methods apply to all kinds of types. Restrictions, 13 // if any, are noted in the documentation for each method. 14 // Use the Kind method to find out the kind of type before 15 // calling kind-specific methods. Calling a method 16 // inappropriate to the kind of type causes a run-time panic. 17 // 18 // Type values are comparable, such as with the == operator, 19 // so they can be used as map keys. 20 // Two Type values are equal if they represent identical types. 21 type Type interface { 22 23 // NumMethod returns the number of methods accessible using Method. 24 // 25 // For a non-interface type, it returns the number of exported methods. 26 // 27 // For an interface type, it returns the number of exported and unexported methods. 28 NumMethod() int 29 30 // Name returns the type's name within its package for a defined type. 31 // For other (non-defined) types it returns the empty string. 32 Name() string 33 34 // PkgPath returns a defined type's package path, that is, the import path 35 // that uniquely identifies the package, such as "encoding/base64". 36 // If the type was predeclared (string, error) or not defined (*T, struct{}, 37 // []int, or A where A is an alias for a non-defined type), the package path 38 // will be the empty string. 39 PkgPath() string 40 41 // String returns a string representation of the type. 42 // The string representation may use shortened package names 43 // (e.g., base64 instead of "encoding/base64") and is not 44 // guaranteed to be unique among types. To test for type identity, 45 // compare the Types directly. 46 String() string 47 48 // Kind returns the specific kind of this type. 49 Kind() Kind 50 51 // ConvertibleTo reports whether a value of the type is convertible to type u. 52 // Even if ConvertibleTo returns true, the conversion may still panic. 53 // For example, a slice of type []T is convertible to *[N]T, 54 // but the conversion will panic if its length is less than N. 55 ConvertibleTo(u Type) bool 56 57 ConvertibleToWithInterface(u Type) bool 58 59 // ChanDir returns a channel type's direction. 60 // It panics if the type's Kind is not Chan. 61 ChanDir() ChanDir 62 63 // IsVariadic reports whether a function type's final input parameter 64 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 65 // implicit actual type []T. 66 // 67 // For concreteness, if t represents func(x int, y ... float64), then 68 // 69 // t.NumIn() == 2 70 // t.In(0) is the reflect.Type for "int" 71 // t.In(1) is the reflect.Type for "[]float64" 72 // t.IsVariadic() == true 73 // 74 // IsVariadic panics if the type's Kind is not Func. 75 IsVariadic() bool 76 77 // Elem returns a type's element type. 78 // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice. 79 Elem() Type 80 81 // Field returns a struct type's i'th field. 82 // It panics if the type's Kind is not Struct. 83 // It panics if i is not in the range [0, NumField()). 84 Field(i int) StructField 85 86 // In returns the type of a function type's i'th input parameter. 87 // It panics if the type's Kind is not Func. 88 // It panics if i is not in the range [0, NumIn()). 89 In(i int) Type 90 91 // Key returns a map type's key type. 92 // It panics if the type's Kind is not Map. 93 Key() Type 94 95 // Len returns an array type's length. 96 // It panics if the type's Kind is not Array. 97 Len() int 98 99 // NumField returns a struct type's field count. 100 // It panics if the type's Kind is not Struct. 101 NumField() int 102 103 // NumIn returns a function type's input parameter count. 104 // It panics if the type's Kind is not Func. 105 NumIn() int 106 107 // NumOut returns a function type's output parameter count. 108 // It panics if the type's Kind is not Func. 109 NumOut() int 110 111 // Out returns the type of a function type's i'th output parameter. 112 // It panics if the type's Kind is not Func. 113 // It panics if i is not in the range [0, NumOut()). 114 Out(i int) Type 115 116 common() *rtype 117 uncommon() *uncommonType 118 } 119 120 var _ Type = (*rtype)(nil) 121 122 // A Kind represents the specific kind of type that a Type represents. 123 // The zero Kind is not a valid kind. 124 type Kind uint 125 126 const ( 127 Invalid Kind = iota 128 Bool 129 Int 130 Int8 131 Int16 132 Int32 133 Int64 134 Uint 135 Uint8 136 Uint16 137 Uint32 138 Uint64 139 Uintptr 140 Float32 141 Float64 142 Complex64 143 Complex128 144 Array 145 Chan 146 Func 147 Interface 148 Map 149 Pointer 150 Slice 151 String 152 Struct 153 UnsafePointer 154 ) 155 156 // Ptr is the old name for the Pointer kind. 157 const Ptr = Pointer 158 159 var kindNames = []string{ 160 Invalid: "invalid", 161 Bool: "bool", 162 Int: "int", 163 Int8: "int8", 164 Int16: "int16", 165 Int32: "int32", 166 Int64: "int64", 167 Uint: "uint", 168 Uint8: "uint8", 169 Uint16: "uint16", 170 Uint32: "uint32", 171 Uint64: "uint64", 172 Uintptr: "uintptr", 173 Float32: "float32", 174 Float64: "float64", 175 Complex64: "complex64", 176 Complex128: "complex128", 177 Array: "array", 178 Chan: "chan", 179 Func: "func", 180 Interface: "interface", 181 Map: "map", 182 Pointer: "ptr", 183 Slice: "slice", 184 String: "string", 185 Struct: "struct", 186 UnsafePointer: "unsafe.Pointer", 187 } 188 189 // String returns the name of k. 190 func (k Kind) String() string { 191 if uint(k) < uint(len(kindNames)) { 192 return kindNames[uint(k)] 193 } 194 return "kind" + strconv.Itoa(int(k)) 195 } 196 197 // tflag is used by an rtype to signal what extra type information is 198 // available in the memory directly following the rtype value. 199 // 200 // tflag values must be kept in sync with copies in: 201 // 202 // cmd/compile/internal/reflectdata/reflect.go 203 // cmd/link/internal/ld/decodesym.go 204 // runtime/type.go 205 type tflag uint8 206 207 const ( 208 // tflagUncommon means that there is a pointer, *uncommonType, 209 // just beyond the outer type structure. 210 // 211 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 212 // then t has uncommonType data and it can be accessed as: 213 // 214 // type tUncommon struct { 215 // structType 216 // u uncommonType 217 // } 218 // u := &(*tUncommon)(unsafe.Pointer(t)).u 219 tflagUncommon tflag = 1 << 0 220 221 // tflagExtraStar means the name in the str field has an 222 // extraneous '*' prefix. This is because for most types T in 223 // a program, the type *T also exists and reusing the str data 224 // saves binary size. 225 tflagExtraStar tflag = 1 << 1 226 227 // tflagNamed means the type has a name. 228 tflagNamed tflag = 1 << 2 229 230 // tflagRegularMemory means that equal and hash functions can treat 231 // this type as a single region of t.size bytes. 232 tflagRegularMemory tflag = 1 << 3 233 ) 234 235 const ( 236 kindDirectIface = 1 << 5 237 kindGCProg = 1 << 6 // Type.gc points to GC program 238 kindMask = (1 << 5) - 1 239 ) 240 241 // resolveNameOff resolves a name offset from a base pointer. 242 // The (*rtype).nameOff method is a convenience wrapper for this function. 243 // Implemented in the runtime package. 244 // 245 //go:linkname resolveNameOff reflect.resolveNameOff 246 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 247 248 // resolveTypeOff resolves an *rtype offset from a base type. 249 // The (*rtype).typeOff method is a convenience wrapper for this function. 250 // Implemented in the runtime package. 251 // 252 //go:linkname resolveTypeOff reflect.resolveTypeOff 253 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 254 255 // resolveTextOff resolves a function pointer offset from a base type. 256 // The (*rtype).textOff method is a convenience wrapper for this function. 257 // Implemented in the runtime package. 258 // 259 //go:linkname resolveTextOff reflect.resolveTextOff 260 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 261 262 //go:linkname addReflectOff reflect.addReflectOff 263 func addReflectOff(ptr unsafe.Pointer) int32 264 265 // resolveReflectName adds a name to the reflection lookup map in the runtime. 266 // It returns a new nameOff that can be used to refer to the pointer. 267 func resolveReflectName(n name) nameOff { 268 return nameOff(addReflectOff(unsafe.Pointer(n.bytes))) 269 } 270 271 // resolveReflectType adds a *rtype to the reflection lookup map in the runtime. 272 // It returns a new typeOff that can be used to refer to the pointer. 273 func resolveReflectType(t *rtype) typeOff { 274 return typeOff(addReflectOff(unsafe.Pointer(t))) 275 } 276 277 // resolveReflectText adds a function pointer to the reflection lookup map in 278 // the runtime. It returns a new textOff that can be used to refer to the 279 // pointer. 280 func resolveReflectText(ptr unsafe.Pointer) textOff { 281 return textOff(addReflectOff(ptr)) 282 } 283 284 type nameOff int32 // offset to a name 285 type typeOff int32 // offset to an *rtype 286 type textOff int32 // offset from top of text section 287 288 func (t *rtype) nameOff(off nameOff) name { 289 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 290 } 291 292 func (t *rtype) typeOff(off typeOff) *rtype { 293 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 294 } 295 296 func (t *rtype) textOff(off textOff) unsafe.Pointer { 297 return resolveTextOff(unsafe.Pointer(t), int32(off)) 298 } 299 300 // rtype is the common implementation of most values. 301 // It is embedded in other struct types. 302 // 303 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 304 type rtype struct { 305 size uintptr 306 ptrdata uintptr // number of bytes in the type that can contain pointers 307 hash uint32 // hash of type; avoids computation in hash tables 308 tflag tflag // extra type information flags 309 align uint8 // alignment of variable with this type 310 fieldAlign uint8 // alignment of struct field with this type 311 kind uint8 // enumeration for C 312 // function for comparing objects of this type 313 // (ptr to object A, ptr to object B) -> ==? 314 equal func(unsafe.Pointer, unsafe.Pointer) bool 315 gcdata *byte // garbage collection data 316 str nameOff // string form 317 ptrToThis typeOff // type for pointer to this type, may be zero 318 } 319 320 type _typePair struct { 321 t1 *rtype 322 t2 *rtype 323 } 324 325 func (t *rtype) hasName() bool { 326 return t.tflag&tflagNamed != 0 327 } 328 329 func (t *rtype) Name() string { 330 if !t.hasName() { 331 return "" 332 } 333 s := t.String() 334 i := len(s) - 1 335 sqBrackets := 0 336 for i >= 0 && (s[i] != '.' || sqBrackets != 0) { 337 switch s[i] { 338 case ']': 339 sqBrackets++ 340 case '[': 341 sqBrackets-- 342 } 343 i-- 344 } 345 return s[i+1:] 346 } 347 348 //go:linkname typelinks reflect.typelinks 349 func typelinks() (sections []unsafe.Pointer, offset [][]int32) 350 351 func rtypeOff(section unsafe.Pointer, off int32) *rtype { 352 return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0")) 353 } 354 355 // typesByString returns the subslice of typelinks() whose elements have 356 // the given string representation. 357 // It may be empty (no known types with that string) or may have 358 // multiple elements (multiple types with that string). 359 func typesByString(s string) []*rtype { 360 sections, offset := typelinks() 361 var ret []*rtype 362 363 for offsI, offs := range offset { 364 section := sections[offsI] 365 366 // We are looking for the first index i where the string becomes >= s. 367 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s). 368 i, j := 0, len(offs) 369 for i < j { 370 h := i + (j-i)>>1 // avoid overflow when computing h 371 // i ≤ h < j 372 if !(rtypeOff(section, offs[h]).String() >= s) { 373 i = h + 1 // preserves f(i-1) == false 374 } else { 375 j = h // preserves f(j) == true 376 } 377 } 378 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 379 380 // Having found the first, linear scan forward to find the last. 381 // We could do a second binary search, but the caller is going 382 // to do a linear scan anyway. 383 for j := i; j < len(offs); j++ { 384 typ := rtypeOff(section, offs[j]) 385 if typ.String() != s { 386 break 387 } 388 ret = append(ret, typ) 389 } 390 } 391 return ret 392 } 393 394 // TypeOf returns the reflection Type that represents the dynamic type of i. 395 // If i is a nil interface value, TypeOf returns nil. 396 func TypeOf(i interface{}) Type { 397 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 398 return toType(eface.typ) 399 } 400 401 // toType converts from a *rtype to a Type that can be returned 402 // to the client of package reflect. In gc, the only concern is that 403 // a nil *rtype must be replaced by a nil Type, but in gccgo this 404 // function takes care of ensuring that multiple *rtype for the same 405 // type are coalesced into a single Type. 406 func toType(t *rtype) Type { 407 if t == nil { 408 return nil 409 } 410 return t 411 } 412 413 // ptrMap is the cache for PointerTo. 414 var ptrMap sync.Map // map[*rtype]*ptrType 415 416 func (t *rtype) ptrTo() *rtype { 417 if t.ptrToThis != 0 { 418 return t.typeOff(t.ptrToThis) 419 } 420 421 // Check the cache. 422 if pi, ok := ptrMap.Load(t); ok { 423 return &pi.(*ptrType).rtype 424 } 425 426 // Look in known types. 427 s := "*" + t.String() 428 for _, tt := range typesByString(s) { 429 p := (*ptrType)(unsafe.Pointer(tt)) 430 if p.elem != t { 431 continue 432 } 433 pi, _ := ptrMap.LoadOrStore(t, p) 434 return &pi.(*ptrType).rtype 435 } 436 437 // Create a new ptrType starting with the description 438 // of an *unsafe.Pointer. 439 var iptr interface{} = (*unsafe.Pointer)(nil) 440 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 441 pp := *prototype 442 443 pp.str = resolveReflectName(newName(s, "", false, false)) 444 pp.ptrToThis = 0 445 446 // For the type structures linked into the binary, the 447 // compiler provides a good hash of the string. 448 // Create a good hash for the new string by using 449 // the FNV-1 hash's mixing function to combine the 450 // old hash and the new "*". 451 pp.hash = fnv1(t.hash, '*') 452 453 pp.elem = t 454 455 pi, _ := ptrMap.LoadOrStore(t, &pp) 456 return &pi.(*ptrType).rtype 457 } 458 459 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 460 func fnv1(x uint32, list ...byte) uint32 { 461 for _, b := range list { 462 x = x*16777619 ^ uint32(b) 463 } 464 return x 465 } 466 467 func (t *rtype) PkgPath() string { 468 if t.tflag&tflagNamed == 0 { 469 return "" 470 } 471 ut := t.uncommon() 472 if ut == nil { 473 return "" 474 } 475 return t.nameOff(ut.pkgPath).name() 476 } 477 478 func (t *rtype) String() string { 479 s := t.nameOff(t.str).name() 480 if t.tflag&tflagExtraStar != 0 { 481 return s[1:] 482 } 483 return s 484 } 485 486 func (t *rtype) ConvertibleTo(u Type) bool { 487 if u == nil { 488 panic("reflect: nil type passed to Type.ConvertibleTo") 489 } 490 uu := u.(*rtype) 491 seen := map[_typePair]struct{}{} 492 return convertOp(uu, t, false, seen) != nil 493 } 494 495 func (t *rtype) ConvertibleToWithInterface(u Type) bool { 496 if u == nil { 497 panic("reflect: nil type passed to Type.ConvertibleTo") 498 } 499 uu := u.(*rtype) 500 seen := map[_typePair]struct{}{} 501 return convertOp(uu, t, true, seen) != nil 502 } 503 504 // implements reports whether the type V implements the interface type T. 505 func implements(T, V *rtype, seen map[_typePair]struct{}) bool { 506 if T.Kind() != Interface { 507 return false 508 } 509 t := (*interfaceType)(unsafe.Pointer(T)) 510 if len(t.methods) == 0 { 511 return true 512 } 513 514 // The same algorithm applies in both cases, but the 515 // method tables for an interface type and a concrete type 516 // are different, so the code is duplicated. 517 // In both cases the algorithm is a linear scan over the two 518 // lists - T's methods and V's methods - simultaneously. 519 // Since method tables are stored in a unique sorted order 520 // (alphabetical, with no duplicate method names), the scan 521 // through V's methods must hit a match for each of T's 522 // methods along the way, or else V does not implement T. 523 // This lets us run the scan in overall linear time instead of 524 // the quadratic time a naive search would require. 525 // See also ../runtime/iface.go. 526 if V.Kind() == Interface { 527 v := (*interfaceType)(unsafe.Pointer(V)) 528 i := 0 529 for j := 0; j < len(v.methods); j++ { 530 tm := &t.methods[i] 531 tmName := t.nameOff(tm.name) 532 vm := &v.methods[j] 533 vmName := V.nameOff(vm.name) 534 if vmName.name() == tmName.name() && haveIdenticalUnderlyingType(V.typeOff(vm.typ), t.typeOff(tm.typ), false, true, seen) { 535 if !tmName.isExported() { 536 tmPkgPath := tmName.pkgPath() 537 if tmPkgPath == "" { 538 tmPkgPath = t.pkgPath.name() 539 } 540 vmPkgPath := vmName.pkgPath() 541 if vmPkgPath == "" { 542 vmPkgPath = v.pkgPath.name() 543 } 544 if tmPkgPath != vmPkgPath { 545 continue 546 } 547 } 548 if i++; i >= len(t.methods) { 549 return true 550 } 551 } 552 } 553 return false 554 } 555 556 v := V.uncommon() 557 if v == nil { 558 return false 559 } 560 i := 0 561 vmethods := v.methods() 562 for j := 0; j < int(v.mcount); j++ { 563 tm := &t.methods[i] 564 tmName := t.nameOff(tm.name) 565 vm := vmethods[j] 566 vmName := V.nameOff(vm.name) 567 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 568 if !tmName.isExported() { 569 tmPkgPath := tmName.pkgPath() 570 if tmPkgPath == "" { 571 tmPkgPath = t.pkgPath.name() 572 } 573 vmPkgPath := vmName.pkgPath() 574 if vmPkgPath == "" { 575 vmPkgPath = V.nameOff(v.pkgPath).name() 576 } 577 if tmPkgPath != vmPkgPath { 578 continue 579 } 580 } 581 if i++; i >= len(t.methods) { 582 return true 583 } 584 } 585 } 586 return false 587 } 588 589 // specialChannelAssignability reports whether a value x of channel type V 590 // can be directly assigned (using memmove) to another channel type T. 591 // https://golang.org/doc/go_spec.html#Assignability 592 // T and V must be both of Chan kind. 593 func specialChannelAssignability(T, V *rtype, seen map[_typePair]struct{}) bool { 594 // Special case: 595 // x is a bidirectional channel value, T is a channel type, 596 // x's type V and T have identical element types, 597 // and at least one of V or T is not a defined type. 598 return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true, true, seen) 599 } 600 601 func (t *rtype) ChanDir() ChanDir { 602 if t.Kind() != Chan { 603 panic("reflect: ChanDir of non-chan type " + t.String()) 604 } 605 tt := (*chanType)(unsafe.Pointer(t)) 606 return ChanDir(tt.dir) 607 } 608 609 func (t *rtype) IsVariadic() bool { 610 if t.Kind() != Func { 611 panic("reflect: IsVariadic of non-func type " + t.String()) 612 } 613 tt := (*funcType)(unsafe.Pointer(t)) 614 return tt.outCount&(1<<15) != 0 615 } 616 617 func (t *rtype) Elem() Type { 618 switch t.Kind() { 619 case Array: 620 tt := (*arrayType)(unsafe.Pointer(t)) 621 return toType(tt.elem) 622 case Chan: 623 tt := (*chanType)(unsafe.Pointer(t)) 624 return toType(tt.elem) 625 case Map: 626 tt := (*mapType)(unsafe.Pointer(t)) 627 return toType(tt.elem) 628 case Pointer: 629 tt := (*ptrType)(unsafe.Pointer(t)) 630 return toType(tt.elem) 631 case Slice: 632 tt := (*sliceType)(unsafe.Pointer(t)) 633 return toType(tt.elem) 634 } 635 panic("reflect: Elem of invalid type " + t.String()) 636 } 637 638 func (t *rtype) Field(i int) StructField { 639 if t.Kind() != Struct { 640 panic("reflect: Field of non-struct type " + t.String()) 641 } 642 tt := (*structType)(unsafe.Pointer(t)) 643 return tt.Field(i) 644 } 645 646 func (t *rtype) In(i int) Type { 647 if t.Kind() != Func { 648 panic("reflect: In of non-func type " + t.String()) 649 } 650 tt := (*funcType)(unsafe.Pointer(t)) 651 return toType(tt.in()[i]) 652 } 653 654 func (t *rtype) Key() Type { 655 if t.Kind() != Map { 656 panic("reflect: Key of non-map type " + t.String()) 657 } 658 tt := (*mapType)(unsafe.Pointer(t)) 659 return toType(tt.key) 660 } 661 662 func (t *rtype) Len() int { 663 if t.Kind() != Array { 664 panic("reflect: Len of non-array type " + t.String()) 665 } 666 tt := (*arrayType)(unsafe.Pointer(t)) 667 return int(tt.len) 668 } 669 670 func (t *rtype) NumField() int { 671 if t.Kind() != Struct { 672 panic("reflect: NumField of non-struct type " + t.String()) 673 } 674 tt := (*structType)(unsafe.Pointer(t)) 675 return len(tt.fields) 676 } 677 678 func (t *rtype) NumIn() int { 679 if t.Kind() != Func { 680 panic("reflect: NumIn of non-func type " + t.String()) 681 } 682 tt := (*funcType)(unsafe.Pointer(t)) 683 return int(tt.inCount) 684 } 685 686 func (t *rtype) NumOut() int { 687 if t.Kind() != Func { 688 panic("reflect: NumOut of non-func type " + t.String()) 689 } 690 tt := (*funcType)(unsafe.Pointer(t)) 691 return len(tt.out()) 692 } 693 694 func (t *rtype) Out(i int) Type { 695 if t.Kind() != Func { 696 panic("reflect: Out of non-func type " + t.String()) 697 } 698 tt := (*funcType)(unsafe.Pointer(t)) 699 return toType(tt.out()[i]) 700 } 701 702 func (t *funcType) in() []*rtype { 703 uadd := unsafe.Sizeof(*t) 704 if t.tflag&tflagUncommon != 0 { 705 uadd += unsafe.Sizeof(uncommonType{}) 706 } 707 if t.inCount == 0 { 708 return nil 709 } 710 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 711 } 712 713 func (t *funcType) out() []*rtype { 714 uadd := unsafe.Sizeof(*t) 715 if t.tflag&tflagUncommon != 0 { 716 uadd += unsafe.Sizeof(uncommonType{}) 717 } 718 outCount := t.outCount & (1<<15 - 1) 719 if outCount == 0 { 720 return nil 721 } 722 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 723 } 724 725 func (t *rtype) common() *rtype { return t } 726 727 // Method on non-interface type 728 type method struct { 729 name nameOff // name of method 730 mtyp typeOff // method type (without receiver) 731 ifn textOff // fn used in interface call (one-word receiver) 732 tfn textOff // fn used for normal method call 733 } 734 735 // uncommonType is present only for defined types or types with methods 736 // (if T is a defined type, the uncommonTypes for T and *T have methods). 737 // Using a pointer to this struct reduces the overall size required 738 // to describe a non-defined type with no methods. 739 type uncommonType struct { 740 pkgPath nameOff // import path; empty for built-in types like int, string 741 mcount uint16 // number of methods 742 xcount uint16 // number of exported methods 743 moff uint32 // offset from this uncommontype to [mcount]method 744 _ uint32 // unused 745 } 746 747 // ChanDir represents a channel type's direction. 748 type ChanDir int 749 750 const ( 751 RecvDir ChanDir = 1 << iota // <-chan 752 SendDir // chan<- 753 BothDir = RecvDir | SendDir // chan 754 ) 755 756 // arrayType represents a fixed array type. 757 type arrayType struct { 758 rtype 759 elem *rtype // array element type 760 slice *rtype // slice type 761 len uintptr 762 } 763 764 // chanType represents a channel type. 765 type chanType struct { 766 rtype 767 elem *rtype // channel element type 768 dir uintptr // channel direction (ChanDir) 769 } 770 771 // funcType represents a function type. 772 // 773 // A *rtype for each in and out parameter is stored in an array that 774 // directly follows the funcType (and possibly its uncommonType). So 775 // a function type with one method, one input, and one output is: 776 // 777 // struct { 778 // funcType 779 // uncommonType 780 // [2]*rtype // [0] is in, [1] is out 781 // } 782 type funcType struct { 783 rtype 784 inCount uint16 785 outCount uint16 // top bit is set if last input parameter is ... 786 } 787 788 // imethod represents a method on an interface type 789 type imethod struct { 790 name nameOff // name of method 791 typ typeOff // .(*FuncType) underneath 792 } 793 794 // interfaceType represents an interface type. 795 type interfaceType struct { 796 rtype 797 pkgPath name // import path 798 methods []imethod // sorted by hash 799 } 800 801 // mapType represents a map type. 802 type mapType struct { 803 rtype 804 key *rtype // map key type 805 elem *rtype // map element (value) type 806 bucket *rtype // internal bucket structure 807 // function for hashing keys (ptr to key, seed) -> hash 808 hasher func(unsafe.Pointer, uintptr) uintptr 809 keysize uint8 // size of key slot 810 valuesize uint8 // size of value slot 811 bucketsize uint16 // size of bucket 812 flags uint32 813 } 814 815 // ptrType represents a pointer type. 816 type ptrType struct { 817 rtype 818 elem *rtype // pointer element (pointed at) type 819 } 820 821 // sliceType represents a slice type. 822 type sliceType struct { 823 rtype 824 elem *rtype // slice element type 825 } 826 827 // Struct field 828 type structField struct { 829 name name // name is always non-empty 830 typ *rtype // type of field 831 offset uintptr // byte offset of field 832 } 833 834 func (f *structField) embedded() bool { 835 return f.name.embedded() 836 } 837 838 // structType represents a struct type. 839 type structType struct { 840 rtype 841 pkgPath name 842 fields []structField // sorted by offset 843 } 844 845 type structTypeUncommon struct { 846 structType 847 u uncommonType 848 } 849 850 // Field returns the i'th struct field. 851 func (t *structType) Field(i int) (f StructField) { 852 if i < 0 || i >= len(t.fields) { 853 panic("reflect: Field index out of bounds") 854 } 855 p := &t.fields[i] 856 f.Type = toType(p.typ) 857 f.Name = p.name.name() 858 f.Anonymous = p.embedded() 859 if !p.name.isExported() { 860 f.PkgPath = t.pkgPath.name() 861 } 862 if tag := p.name.tag(); tag != "" { 863 f.Tag = StructTag(tag) 864 } 865 f.Offset = p.offset 866 867 // NOTE(rsc): This is the only allocation in the interface 868 // presented by a reflect.Type. It would be nice to avoid, 869 // at least in the common cases, but we need to make sure 870 // that misbehaving clients of reflect cannot affect other 871 // uses of reflect. One possibility is CL 5371098, but we 872 // postponed that ugliness until there is a demonstrated 873 // need for the performance. This is issue 2320. 874 f.Index = []int{i} 875 return 876 } 877 878 // name is an encoded type name with optional extra data. 879 // 880 // The first byte is a bit field containing: 881 // 882 // 1<<0 the name is exported 883 // 1<<1 tag data follows the name 884 // 1<<2 pkgPath nameOff follows the name and tag 885 // 1<<3 the name is of an embedded (a.k.a. anonymous) field 886 // 887 // Following that, there is a varint-encoded length of the name, 888 // followed by the name itself. 889 // 890 // If tag data is present, it also has a varint-encoded length 891 // followed by the tag itself. 892 // 893 // If the import path follows, then 4 bytes at the end of 894 // the data form a nameOff. The import path is only set for concrete 895 // methods that are defined in a different package than their type. 896 // 897 // If a name starts with "*", then the exported bit represents 898 // whether the pointed to type is exported. 899 // 900 // Note: this encoding must match here and in: 901 // cmd/compile/internal/reflectdata/reflect.go 902 // runtime/type.go 903 // internal/reflectlite/type.go 904 // cmd/link/internal/ld/decodesym.go 905 906 type name struct { 907 bytes *byte 908 } 909 910 func (n name) data(off int, whySafe string) *byte { 911 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) 912 } 913 914 func (n name) isExported() bool { 915 return (*n.bytes)&(1<<0) != 0 916 } 917 918 func (n name) hasTag() bool { 919 return (*n.bytes)&(1<<1) != 0 920 } 921 922 func (n name) embedded() bool { 923 return (*n.bytes)&(1<<3) != 0 924 } 925 926 func (n name) name() (s string) { 927 if n.bytes == nil { 928 return 929 } 930 i, l := n.readVarint(1) 931 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 932 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) 933 hdr.Len = l 934 return 935 } 936 937 func (n name) tag() (s string) { 938 if !n.hasTag() { 939 return "" 940 } 941 i, l := n.readVarint(1) 942 i2, l2 := n.readVarint(1 + i + l) 943 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 944 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string")) 945 hdr.Len = l2 946 return 947 } 948 949 func (n name) pkgPath() string { 950 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 951 return "" 952 } 953 i, l := n.readVarint(1) 954 off := 1 + i + l 955 if n.hasTag() { 956 i2, l2 := n.readVarint(off) 957 off += i2 + l2 958 } 959 var nameOff int32 960 // Note that this field may not be aligned in memory, 961 // so we cannot use a direct int32 assignment here. 962 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 963 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 964 return pkgPathName.name() 965 } 966 967 func newName(n, tag string, exported, embedded bool) name { 968 if len(n) >= 1<<29 { 969 panic("reflect.nameFrom: name too long: " + n[:1024] + "...") 970 } 971 if len(tag) >= 1<<29 { 972 panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...") 973 } 974 var nameLen [10]byte 975 var tagLen [10]byte 976 nameLenLen := writeVarint(nameLen[:], len(n)) 977 tagLenLen := writeVarint(tagLen[:], len(tag)) 978 979 var bits byte 980 l := 1 + nameLenLen + len(n) 981 if exported { 982 bits |= 1 << 0 983 } 984 if len(tag) > 0 { 985 l += tagLenLen + len(tag) 986 bits |= 1 << 1 987 } 988 if embedded { 989 bits |= 1 << 3 990 } 991 992 b := make([]byte, l) 993 b[0] = bits 994 copy(b[1:], nameLen[:nameLenLen]) 995 copy(b[1+nameLenLen:], n) 996 if len(tag) > 0 { 997 tb := b[1+nameLenLen+len(n):] 998 copy(tb, tagLen[:tagLenLen]) 999 copy(tb[tagLenLen:], tag) 1000 } 1001 1002 return name{bytes: &b[0]} 1003 } 1004 1005 type StructTag string 1006 1007 // A StructField describes a single field in a struct. 1008 type StructField struct { 1009 // Name is the field name. 1010 Name string 1011 1012 // PkgPath is the package path that qualifies a lower case (unexported) 1013 // field name. It is empty for upper case (exported) field names. 1014 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 1015 PkgPath string 1016 1017 Type Type // field type 1018 Tag StructTag // field tag string 1019 Offset uintptr // offset within struct, in bytes 1020 Index []int // index sequence for Type.FieldByIndex 1021 Anonymous bool // is an embedded field 1022 } 1023 1024 // readVarint parses a varint as encoded by encoding/binary. 1025 // It returns the number of encoded bytes and the encoded value. 1026 func (n name) readVarint(off int) (int, int) { 1027 v := 0 1028 for i := uint(0); ; i++ { 1029 x := *n.data(off+int(i), "read varint") 1030 v += int(x&0x7f) << (7 * i) 1031 if x&0x80 == 0 { 1032 return int(i + 1), v 1033 } 1034 } 1035 } 1036 1037 // writeVarint writes n to buf in varint form. Returns the 1038 // number of bytes written. n must be nonnegative. 1039 // Writes at most 10 bytes. 1040 func writeVarint(buf []byte, n int) int { 1041 for i := 0; ; i++ { 1042 b := byte(n & 0x7f) 1043 n >>= 7 1044 if n == 0 { 1045 buf[i] = b 1046 return i + 1 1047 } 1048 buf[i] = b | 0x80 1049 } 1050 } 1051 1052 // add returns p+x. 1053 // 1054 // The whySafe string is ignored, so that the function still inlines 1055 // as efficiently as p+x, but all call sites should use the string to 1056 // record why the addition is safe, which is to say why the addition 1057 // does not cause x to advance to the very end of p's allocation 1058 // and therefore point incorrectly at the next block in memory. 1059 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 1060 return unsafe.Pointer(uintptr(p) + x) 1061 } 1062 1063 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 1064 1065 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 1066 1067 func (t *rtype) NumMethod() int { 1068 if t.Kind() == Interface { 1069 tt := (*interfaceType)(unsafe.Pointer(t)) 1070 return tt.NumMethod() 1071 } 1072 return len(t.exportedMethods()) 1073 } 1074 1075 func (t *rtype) uncommon() *uncommonType { 1076 if t.tflag&tflagUncommon == 0 { 1077 return nil 1078 } 1079 switch t.Kind() { 1080 case Struct: 1081 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 1082 case Pointer: 1083 type u struct { 1084 ptrType 1085 u uncommonType 1086 } 1087 return &(*u)(unsafe.Pointer(t)).u 1088 case Func: 1089 type u struct { 1090 funcType 1091 u uncommonType 1092 } 1093 return &(*u)(unsafe.Pointer(t)).u 1094 case Slice: 1095 type u struct { 1096 sliceType 1097 u uncommonType 1098 } 1099 return &(*u)(unsafe.Pointer(t)).u 1100 case Array: 1101 type u struct { 1102 arrayType 1103 u uncommonType 1104 } 1105 return &(*u)(unsafe.Pointer(t)).u 1106 case Chan: 1107 type u struct { 1108 chanType 1109 u uncommonType 1110 } 1111 return &(*u)(unsafe.Pointer(t)).u 1112 case Map: 1113 type u struct { 1114 mapType 1115 u uncommonType 1116 } 1117 return &(*u)(unsafe.Pointer(t)).u 1118 case Interface: 1119 type u struct { 1120 interfaceType 1121 u uncommonType 1122 } 1123 return &(*u)(unsafe.Pointer(t)).u 1124 default: 1125 type u struct { 1126 rtype 1127 u uncommonType 1128 } 1129 return &(*u)(unsafe.Pointer(t)).u 1130 } 1131 } 1132 1133 func (t *rtype) exportedMethods() []method { 1134 ut := t.uncommon() 1135 if ut == nil { 1136 return nil 1137 } 1138 return ut.exportedMethods() 1139 } 1140 1141 func (t *uncommonType) methods() []method { 1142 if t.mcount == 0 { 1143 return nil 1144 } 1145 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 1146 } 1147 1148 func (t *uncommonType) exportedMethods() []method { 1149 if t.xcount == 0 { 1150 return nil 1151 } 1152 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 1153 } 1154 1155 // NumMethod returns the number of interface methods in the type's method set. 1156 func (t *interfaceType) NumMethod() int { return len(t.methods) }