github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/reflect/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 reflect 17 18 import ( 19 "internal/goarch" 20 "internal/unsafeheader" 21 "strconv" 22 "sync" 23 "unicode" 24 "unicode/utf8" 25 "unsafe" 26 ) 27 28 // Type is the representation of a Go type. 29 // 30 // Not all methods apply to all kinds of types. Restrictions, 31 // if any, are noted in the documentation for each method. 32 // Use the Kind method to find out the kind of type before 33 // calling kind-specific methods. Calling a method 34 // inappropriate to the kind of type causes a run-time panic. 35 // 36 // Type values are comparable, such as with the == operator, 37 // so they can be used as map keys. 38 // Two Type values are equal if they represent identical types. 39 type Type interface { 40 // Methods applicable to all types. 41 42 // Align returns the alignment in bytes of a value of 43 // this type when allocated in memory. 44 Align() int 45 46 // FieldAlign returns the alignment in bytes of a value of 47 // this type when used as a field in a struct. 48 FieldAlign() int 49 50 // Method returns the i'th method in the type's method set. 51 // It panics if i is not in the range [0, NumMethod()). 52 // 53 // For a non-interface type T or *T, the returned Method's Type and Func 54 // fields describe a function whose first argument is the receiver, 55 // and only exported methods are accessible. 56 // 57 // For an interface type, the returned Method's Type field gives the 58 // method signature, without a receiver, and the Func field is nil. 59 // 60 // Methods are sorted in lexicographic order. 61 Method(int) Method 62 63 // MethodByName returns the method with that name in the type's 64 // method set and a boolean indicating if the method was found. 65 // 66 // For a non-interface type T or *T, the returned Method's Type and Func 67 // fields describe a function whose first argument is the receiver. 68 // 69 // For an interface type, the returned Method's Type field gives the 70 // method signature, without a receiver, and the Func field is nil. 71 MethodByName(string) (Method, bool) 72 73 // NumMethod returns the number of methods accessible using Method. 74 // 75 // For a non-interface type, it returns the number of exported methods. 76 // 77 // For an interface type, it returns the number of exported and unexported methods. 78 NumMethod() int 79 80 // Name returns the type's name within its package for a defined type. 81 // For other (non-defined) types it returns the empty string. 82 Name() string 83 84 // PkgPath returns a defined type's package path, that is, the import path 85 // that uniquely identifies the package, such as "encoding/base64". 86 // If the type was predeclared (string, error) or not defined (*T, struct{}, 87 // []int, or A where A is an alias for a non-defined type), the package path 88 // will be the empty string. 89 PkgPath() string 90 91 // Size returns the number of bytes needed to store 92 // a value of the given type; it is analogous to unsafe.Sizeof. 93 Size() uintptr 94 95 // String returns a string representation of the type. 96 // The string representation may use shortened package names 97 // (e.g., base64 instead of "encoding/base64") and is not 98 // guaranteed to be unique among types. To test for type identity, 99 // compare the Types directly. 100 String() string 101 102 // Kind returns the specific kind of this type. 103 Kind() Kind 104 105 // Implements reports whether the type implements the interface type u. 106 Implements(u Type) bool 107 108 // AssignableTo reports whether a value of the type is assignable to type u. 109 AssignableTo(u Type) bool 110 111 // ConvertibleTo reports whether a value of the type is convertible to type u. 112 // Even if ConvertibleTo returns true, the conversion may still panic. 113 // For example, a slice of type []T is convertible to *[N]T, 114 // but the conversion will panic if its length is less than N. 115 ConvertibleTo(u Type) bool 116 117 // Comparable reports whether values of this type are comparable. 118 // Even if Comparable returns true, the comparison may still panic. 119 // For example, values of interface type are comparable, 120 // but the comparison will panic if their dynamic type is not comparable. 121 Comparable() bool 122 123 // Methods applicable only to some types, depending on Kind. 124 // The methods allowed for each kind are: 125 // 126 // Int*, Uint*, Float*, Complex*: Bits 127 // Array: Elem, Len 128 // Chan: ChanDir, Elem 129 // Func: In, NumIn, Out, NumOut, IsVariadic. 130 // Map: Key, Elem 131 // Pointer: Elem 132 // Slice: Elem 133 // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField 134 135 // Bits returns the size of the type in bits. 136 // It panics if the type's Kind is not one of the 137 // sized or unsized Int, Uint, Float, or Complex kinds. 138 Bits() int 139 140 // ChanDir returns a channel type's direction. 141 // It panics if the type's Kind is not Chan. 142 ChanDir() ChanDir 143 144 // IsVariadic reports whether a function type's final input parameter 145 // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's 146 // implicit actual type []T. 147 // 148 // For concreteness, if t represents func(x int, y ... float64), then 149 // 150 // t.NumIn() == 2 151 // t.In(0) is the reflect.Type for "int" 152 // t.In(1) is the reflect.Type for "[]float64" 153 // t.IsVariadic() == true 154 // 155 // IsVariadic panics if the type's Kind is not Func. 156 IsVariadic() bool 157 158 // Elem returns a type's element type. 159 // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice. 160 Elem() Type 161 162 // Field returns a struct type's i'th field. 163 // It panics if the type's Kind is not Struct. 164 // It panics if i is not in the range [0, NumField()). 165 Field(i int) StructField 166 167 // FieldByIndex returns the nested field corresponding 168 // to the index sequence. It is equivalent to calling Field 169 // successively for each index i. 170 // It panics if the type's Kind is not Struct. 171 FieldByIndex(index []int) StructField 172 173 // FieldByName returns the struct field with the given name 174 // and a boolean indicating if the field was found. 175 FieldByName(name string) (StructField, bool) 176 177 // FieldByNameFunc returns the struct field with a name 178 // that satisfies the match function and a boolean indicating if 179 // the field was found. 180 // 181 // FieldByNameFunc considers the fields in the struct itself 182 // and then the fields in any embedded structs, in breadth first order, 183 // stopping at the shallowest nesting depth containing one or more 184 // fields satisfying the match function. If multiple fields at that depth 185 // satisfy the match function, they cancel each other 186 // and FieldByNameFunc returns no match. 187 // This behavior mirrors Go's handling of name lookup in 188 // structs containing embedded fields. 189 FieldByNameFunc(match func(string) bool) (StructField, bool) 190 191 // In returns the type of a function type's i'th input parameter. 192 // It panics if the type's Kind is not Func. 193 // It panics if i is not in the range [0, NumIn()). 194 In(i int) Type 195 196 // Key returns a map type's key type. 197 // It panics if the type's Kind is not Map. 198 Key() Type 199 200 // Len returns an array type's length. 201 // It panics if the type's Kind is not Array. 202 Len() int 203 204 // NumField returns a struct type's field count. 205 // It panics if the type's Kind is not Struct. 206 NumField() int 207 208 // NumIn returns a function type's input parameter count. 209 // It panics if the type's Kind is not Func. 210 NumIn() int 211 212 // NumOut returns a function type's output parameter count. 213 // It panics if the type's Kind is not Func. 214 NumOut() int 215 216 // Out returns the type of a function type's i'th output parameter. 217 // It panics if the type's Kind is not Func. 218 // It panics if i is not in the range [0, NumOut()). 219 Out(i int) Type 220 221 common() *rtype 222 uncommon() *uncommonType 223 } 224 225 // BUG(rsc): FieldByName and related functions consider struct field names to be equal 226 // if the names are equal, even if they are unexported names originating 227 // in different packages. The practical effect of this is that the result of 228 // t.FieldByName("x") is not well defined if the struct type t contains 229 // multiple fields named x (embedded from different packages). 230 // FieldByName may return one of the fields named x or may report that there are none. 231 // See https://golang.org/issue/4876 for more details. 232 233 /* 234 * These data structures are known to the compiler (../cmd/compile/internal/reflectdata/reflect.go). 235 * A few are known to ../runtime/type.go to convey to debuggers. 236 * They are also known to ../runtime/type.go. 237 */ 238 239 // A Kind represents the specific kind of type that a Type represents. 240 // The zero Kind is not a valid kind. 241 type Kind uint 242 243 const ( 244 Invalid Kind = iota 245 Bool 246 Int 247 Int8 248 Int16 249 Int32 250 Int64 251 Uint 252 Uint8 253 Uint16 254 Uint32 255 Uint64 256 Uintptr 257 Float32 258 Float64 259 Complex64 260 Complex128 261 Array 262 Chan 263 Func 264 Interface 265 Map 266 Pointer 267 Slice 268 String 269 Struct 270 UnsafePointer 271 ) 272 273 // Ptr is the old name for the Pointer kind. 274 const Ptr = Pointer 275 276 // tflag is used by an rtype to signal what extra type information is 277 // available in the memory directly following the rtype value. 278 // 279 // tflag values must be kept in sync with copies in: 280 // 281 // cmd/compile/internal/reflectdata/reflect.go 282 // cmd/link/internal/ld/decodesym.go 283 // runtime/type.go 284 type tflag uint8 285 286 const ( 287 // tflagUncommon means that there is a pointer, *uncommonType, 288 // just beyond the outer type structure. 289 // 290 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 291 // then t has uncommonType data and it can be accessed as: 292 // 293 // type tUncommon struct { 294 // structType 295 // u uncommonType 296 // } 297 // u := &(*tUncommon)(unsafe.Pointer(t)).u 298 tflagUncommon tflag = 1 << 0 299 300 // tflagExtraStar means the name in the str field has an 301 // extraneous '*' prefix. This is because for most types T in 302 // a program, the type *T also exists and reusing the str data 303 // saves binary size. 304 tflagExtraStar tflag = 1 << 1 305 306 // tflagNamed means the type has a name. 307 tflagNamed tflag = 1 << 2 308 309 // tflagRegularMemory means that equal and hash functions can treat 310 // this type as a single region of t.size bytes. 311 tflagRegularMemory tflag = 1 << 3 312 ) 313 314 // rtype is the common implementation of most values. 315 // It is embedded in other struct types. 316 // 317 // rtype must be kept in sync with ../runtime/type.go:/^type._type. 318 type rtype struct { 319 size uintptr 320 ptrdata uintptr // number of bytes in the type that can contain pointers 321 hash uint32 // hash of type; avoids computation in hash tables 322 tflag tflag // extra type information flags 323 align uint8 // alignment of variable with this type 324 fieldAlign uint8 // alignment of struct field with this type 325 kind uint8 // enumeration for C 326 // function for comparing objects of this type 327 // (ptr to object A, ptr to object B) -> ==? 328 equal func(unsafe.Pointer, unsafe.Pointer) bool 329 gcdata *byte // garbage collection data 330 str nameOff // string form 331 ptrToThis typeOff // type for pointer to this type, may be zero 332 } 333 334 // Method on non-interface type 335 type method struct { 336 name nameOff // name of method 337 mtyp typeOff // method type (without receiver) 338 ifn textOff // fn used in interface call (one-word receiver) 339 tfn textOff // fn used for normal method call 340 } 341 342 // uncommonType is present only for defined types or types with methods 343 // (if T is a defined type, the uncommonTypes for T and *T have methods). 344 // Using a pointer to this struct reduces the overall size required 345 // to describe a non-defined type with no methods. 346 type uncommonType struct { 347 pkgPath nameOff // import path; empty for built-in types like int, string 348 mcount uint16 // number of methods 349 xcount uint16 // number of exported methods 350 moff uint32 // offset from this uncommontype to [mcount]method 351 _ uint32 // unused 352 } 353 354 // ChanDir represents a channel type's direction. 355 type ChanDir int 356 357 const ( 358 RecvDir ChanDir = 1 << iota // <-chan 359 SendDir // chan<- 360 BothDir = RecvDir | SendDir // chan 361 ) 362 363 // arrayType represents a fixed array type. 364 type arrayType struct { 365 rtype 366 elem *rtype // array element type 367 slice *rtype // slice type 368 len uintptr 369 } 370 371 // chanType represents a channel type. 372 type chanType struct { 373 rtype 374 elem *rtype // channel element type 375 dir uintptr // channel direction (ChanDir) 376 } 377 378 // funcType represents a function type. 379 // 380 // A *rtype for each in and out parameter is stored in an array that 381 // directly follows the funcType (and possibly its uncommonType). So 382 // a function type with one method, one input, and one output is: 383 // 384 // struct { 385 // funcType 386 // uncommonType 387 // [2]*rtype // [0] is in, [1] is out 388 // } 389 type funcType struct { 390 rtype 391 inCount uint16 392 outCount uint16 // top bit is set if last input parameter is ... 393 } 394 395 // imethod represents a method on an interface type 396 type imethod struct { 397 name nameOff // name of method 398 typ typeOff // .(*FuncType) underneath 399 } 400 401 // interfaceType represents an interface type. 402 type interfaceType struct { 403 rtype 404 pkgPath name // import path 405 methods []imethod // sorted by hash 406 } 407 408 // mapType represents a map type. 409 type mapType struct { 410 rtype 411 key *rtype // map key type 412 elem *rtype // map element (value) type 413 bucket *rtype // internal bucket structure 414 // function for hashing keys (ptr to key, seed) -> hash 415 hasher func(unsafe.Pointer, uintptr) uintptr 416 keysize uint8 // size of key slot 417 valuesize uint8 // size of value slot 418 bucketsize uint16 // size of bucket 419 flags uint32 420 } 421 422 // ptrType represents a pointer type. 423 type ptrType struct { 424 rtype 425 elem *rtype // pointer element (pointed at) type 426 } 427 428 // sliceType represents a slice type. 429 type sliceType struct { 430 rtype 431 elem *rtype // slice element type 432 } 433 434 // Struct field 435 type structField struct { 436 name name // name is always non-empty 437 typ *rtype // type of field 438 offset uintptr // byte offset of field 439 } 440 441 func (f *structField) embedded() bool { 442 return f.name.embedded() 443 } 444 445 // structType represents a struct type. 446 type structType struct { 447 rtype 448 pkgPath name 449 fields []structField // sorted by offset 450 } 451 452 // name is an encoded type name with optional extra data. 453 // 454 // The first byte is a bit field containing: 455 // 456 // 1<<0 the name is exported 457 // 1<<1 tag data follows the name 458 // 1<<2 pkgPath nameOff follows the name and tag 459 // 1<<3 the name is of an embedded (a.k.a. anonymous) field 460 // 461 // Following that, there is a varint-encoded length of the name, 462 // followed by the name itself. 463 // 464 // If tag data is present, it also has a varint-encoded length 465 // followed by the tag itself. 466 // 467 // If the import path follows, then 4 bytes at the end of 468 // the data form a nameOff. The import path is only set for concrete 469 // methods that are defined in a different package than their type. 470 // 471 // If a name starts with "*", then the exported bit represents 472 // whether the pointed to type is exported. 473 // 474 // Note: this encoding must match here and in: 475 // cmd/compile/internal/reflectdata/reflect.go 476 // runtime/type.go 477 // internal/reflectlite/type.go 478 // cmd/link/internal/ld/decodesym.go 479 480 type name struct { 481 bytes *byte 482 } 483 484 func (n name) data(off int, whySafe string) *byte { 485 return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) 486 } 487 488 func (n name) isExported() bool { 489 return (*n.bytes)&(1<<0) != 0 490 } 491 492 func (n name) hasTag() bool { 493 return (*n.bytes)&(1<<1) != 0 494 } 495 496 func (n name) embedded() bool { 497 return (*n.bytes)&(1<<3) != 0 498 } 499 500 // readVarint parses a varint as encoded by encoding/binary. 501 // It returns the number of encoded bytes and the encoded value. 502 func (n name) readVarint(off int) (int, int) { 503 v := 0 504 for i := 0; ; i++ { 505 x := *n.data(off+i, "read varint") 506 v += int(x&0x7f) << (7 * i) 507 if x&0x80 == 0 { 508 return i + 1, v 509 } 510 } 511 } 512 513 // writeVarint writes n to buf in varint form. Returns the 514 // number of bytes written. n must be nonnegative. 515 // Writes at most 10 bytes. 516 func writeVarint(buf []byte, n int) int { 517 for i := 0; ; i++ { 518 b := byte(n & 0x7f) 519 n >>= 7 520 if n == 0 { 521 buf[i] = b 522 return i + 1 523 } 524 buf[i] = b | 0x80 525 } 526 } 527 528 func (n name) name() (s string) { 529 if n.bytes == nil { 530 return 531 } 532 i, l := n.readVarint(1) 533 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 534 hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) 535 hdr.Len = l 536 return 537 } 538 539 func (n name) tag() (s string) { 540 if !n.hasTag() { 541 return "" 542 } 543 i, l := n.readVarint(1) 544 i2, l2 := n.readVarint(1 + i + l) 545 hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) 546 hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string")) 547 hdr.Len = l2 548 return 549 } 550 551 func (n name) pkgPath() string { 552 if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 { 553 return "" 554 } 555 i, l := n.readVarint(1) 556 off := 1 + i + l 557 if n.hasTag() { 558 i2, l2 := n.readVarint(off) 559 off += i2 + l2 560 } 561 var nameOff int32 562 // Note that this field may not be aligned in memory, 563 // so we cannot use a direct int32 assignment here. 564 copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:]) 565 pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))} 566 return pkgPathName.name() 567 } 568 569 func newName(n, tag string, exported, embedded bool) name { 570 if len(n) >= 1<<29 { 571 panic("reflect.nameFrom: name too long: " + n[:1024] + "...") 572 } 573 if len(tag) >= 1<<29 { 574 panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...") 575 } 576 var nameLen [10]byte 577 var tagLen [10]byte 578 nameLenLen := writeVarint(nameLen[:], len(n)) 579 tagLenLen := writeVarint(tagLen[:], len(tag)) 580 581 var bits byte 582 l := 1 + nameLenLen + len(n) 583 if exported { 584 bits |= 1 << 0 585 } 586 if len(tag) > 0 { 587 l += tagLenLen + len(tag) 588 bits |= 1 << 1 589 } 590 if embedded { 591 bits |= 1 << 3 592 } 593 594 b := make([]byte, l) 595 b[0] = bits 596 copy(b[1:], nameLen[:nameLenLen]) 597 copy(b[1+nameLenLen:], n) 598 if len(tag) > 0 { 599 tb := b[1+nameLenLen+len(n):] 600 copy(tb, tagLen[:tagLenLen]) 601 copy(tb[tagLenLen:], tag) 602 } 603 604 return name{bytes: &b[0]} 605 } 606 607 /* 608 * The compiler knows the exact layout of all the data structures above. 609 * The compiler does not know about the data structures and methods below. 610 */ 611 612 // Method represents a single method. 613 type Method struct { 614 // Name is the method name. 615 Name string 616 617 // PkgPath is the package path that qualifies a lower case (unexported) 618 // method name. It is empty for upper case (exported) method names. 619 // The combination of PkgPath and Name uniquely identifies a method 620 // in a method set. 621 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 622 PkgPath string 623 624 Type Type // method type 625 Func Value // func with receiver as first argument 626 Index int // index for Type.Method 627 } 628 629 // IsExported reports whether the method is exported. 630 func (m Method) IsExported() bool { 631 return m.PkgPath == "" 632 } 633 634 const ( 635 kindDirectIface = 1 << 5 636 kindGCProg = 1 << 6 // Type.gc points to GC program 637 kindMask = (1 << 5) - 1 638 ) 639 640 // String returns the name of k. 641 func (k Kind) String() string { 642 if uint(k) < uint(len(kindNames)) { 643 return kindNames[uint(k)] 644 } 645 return "kind" + strconv.Itoa(int(k)) 646 } 647 648 var kindNames = []string{ 649 Invalid: "invalid", 650 Bool: "bool", 651 Int: "int", 652 Int8: "int8", 653 Int16: "int16", 654 Int32: "int32", 655 Int64: "int64", 656 Uint: "uint", 657 Uint8: "uint8", 658 Uint16: "uint16", 659 Uint32: "uint32", 660 Uint64: "uint64", 661 Uintptr: "uintptr", 662 Float32: "float32", 663 Float64: "float64", 664 Complex64: "complex64", 665 Complex128: "complex128", 666 Array: "array", 667 Chan: "chan", 668 Func: "func", 669 Interface: "interface", 670 Map: "map", 671 Pointer: "ptr", 672 Slice: "slice", 673 String: "string", 674 Struct: "struct", 675 UnsafePointer: "unsafe.Pointer", 676 } 677 678 func (t *uncommonType) methods() []method { 679 if t.mcount == 0 { 680 return nil 681 } 682 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] 683 } 684 685 func (t *uncommonType) exportedMethods() []method { 686 if t.xcount == 0 { 687 return nil 688 } 689 return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount] 690 } 691 692 // resolveNameOff resolves a name offset from a base pointer. 693 // The (*rtype).nameOff method is a convenience wrapper for this function. 694 // Implemented in the runtime package. 695 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 696 697 // resolveTypeOff resolves an *rtype offset from a base type. 698 // The (*rtype).typeOff method is a convenience wrapper for this function. 699 // Implemented in the runtime package. 700 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 701 702 // resolveTextOff resolves a function pointer offset from a base type. 703 // The (*rtype).textOff method is a convenience wrapper for this function. 704 // Implemented in the runtime package. 705 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 706 707 // addReflectOff adds a pointer to the reflection lookup map in the runtime. 708 // It returns a new ID that can be used as a typeOff or textOff, and will 709 // be resolved correctly. Implemented in the runtime package. 710 func addReflectOff(ptr unsafe.Pointer) int32 711 712 // resolveReflectName adds a name to the reflection lookup map in the runtime. 713 // It returns a new nameOff that can be used to refer to the pointer. 714 func resolveReflectName(n name) nameOff { 715 return nameOff(addReflectOff(unsafe.Pointer(n.bytes))) 716 } 717 718 // resolveReflectType adds a *rtype to the reflection lookup map in the runtime. 719 // It returns a new typeOff that can be used to refer to the pointer. 720 func resolveReflectType(t *rtype) typeOff { 721 return typeOff(addReflectOff(unsafe.Pointer(t))) 722 } 723 724 // resolveReflectText adds a function pointer to the reflection lookup map in 725 // the runtime. It returns a new textOff that can be used to refer to the 726 // pointer. 727 func resolveReflectText(ptr unsafe.Pointer) textOff { 728 return textOff(addReflectOff(ptr)) 729 } 730 731 type nameOff int32 // offset to a name 732 type typeOff int32 // offset to an *rtype 733 type textOff int32 // offset from top of text section 734 735 func (t *rtype) nameOff(off nameOff) name { 736 return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))} 737 } 738 739 func (t *rtype) typeOff(off typeOff) *rtype { 740 return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 741 } 742 743 func (t *rtype) textOff(off textOff) unsafe.Pointer { 744 return resolveTextOff(unsafe.Pointer(t), int32(off)) 745 } 746 747 func (t *rtype) uncommon() *uncommonType { 748 if t.tflag&tflagUncommon == 0 { 749 return nil 750 } 751 switch t.Kind() { 752 case Struct: 753 return &(*structTypeUncommon)(unsafe.Pointer(t)).u 754 case Pointer: 755 type u struct { 756 ptrType 757 u uncommonType 758 } 759 return &(*u)(unsafe.Pointer(t)).u 760 case Func: 761 type u struct { 762 funcType 763 u uncommonType 764 } 765 return &(*u)(unsafe.Pointer(t)).u 766 case Slice: 767 type u struct { 768 sliceType 769 u uncommonType 770 } 771 return &(*u)(unsafe.Pointer(t)).u 772 case Array: 773 type u struct { 774 arrayType 775 u uncommonType 776 } 777 return &(*u)(unsafe.Pointer(t)).u 778 case Chan: 779 type u struct { 780 chanType 781 u uncommonType 782 } 783 return &(*u)(unsafe.Pointer(t)).u 784 case Map: 785 type u struct { 786 mapType 787 u uncommonType 788 } 789 return &(*u)(unsafe.Pointer(t)).u 790 case Interface: 791 type u struct { 792 interfaceType 793 u uncommonType 794 } 795 return &(*u)(unsafe.Pointer(t)).u 796 default: 797 type u struct { 798 rtype 799 u uncommonType 800 } 801 return &(*u)(unsafe.Pointer(t)).u 802 } 803 } 804 805 func (t *rtype) String() string { 806 s := t.nameOff(t.str).name() 807 if t.tflag&tflagExtraStar != 0 { 808 return s[1:] 809 } 810 return s 811 } 812 813 func (t *rtype) Size() uintptr { return t.size } 814 815 func (t *rtype) Bits() int { 816 if t == nil { 817 panic("reflect: Bits of nil Type") 818 } 819 k := t.Kind() 820 if k < Int || k > Complex128 { 821 panic("reflect: Bits of non-arithmetic Type " + t.String()) 822 } 823 return int(t.size) * 8 824 } 825 826 func (t *rtype) Align() int { return int(t.align) } 827 828 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) } 829 830 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 831 832 func (t *rtype) pointers() bool { return t.ptrdata != 0 } 833 834 func (t *rtype) common() *rtype { return t } 835 836 func (t *rtype) exportedMethods() []method { 837 ut := t.uncommon() 838 if ut == nil { 839 return nil 840 } 841 return ut.exportedMethods() 842 } 843 844 func (t *rtype) NumMethod() int { 845 if t.Kind() == Interface { 846 tt := (*interfaceType)(unsafe.Pointer(t)) 847 return tt.NumMethod() 848 } 849 return len(t.exportedMethods()) 850 } 851 852 func (t *rtype) Method(i int) (m Method) { 853 if t.Kind() == Interface { 854 tt := (*interfaceType)(unsafe.Pointer(t)) 855 return tt.Method(i) 856 } 857 methods := t.exportedMethods() 858 if i < 0 || i >= len(methods) { 859 panic("reflect: Method index out of range") 860 } 861 p := methods[i] 862 pname := t.nameOff(p.name) 863 m.Name = pname.name() 864 fl := flag(Func) 865 mtyp := t.typeOff(p.mtyp) 866 ft := (*funcType)(unsafe.Pointer(mtyp)) 867 in := make([]Type, 0, 1+len(ft.in())) 868 in = append(in, t) 869 for _, arg := range ft.in() { 870 in = append(in, arg) 871 } 872 out := make([]Type, 0, len(ft.out())) 873 for _, ret := range ft.out() { 874 out = append(out, ret) 875 } 876 mt := FuncOf(in, out, ft.IsVariadic()) 877 m.Type = mt 878 tfn := t.textOff(p.tfn) 879 fn := unsafe.Pointer(&tfn) 880 m.Func = Value{mt.(*rtype), fn, fl} 881 882 m.Index = i 883 return m 884 } 885 886 func (t *rtype) MethodByName(name string) (m Method, ok bool) { 887 if t.Kind() == Interface { 888 tt := (*interfaceType)(unsafe.Pointer(t)) 889 return tt.MethodByName(name) 890 } 891 ut := t.uncommon() 892 if ut == nil { 893 return Method{}, false 894 } 895 896 methods := ut.exportedMethods() 897 898 // We are looking for the first index i where the string becomes >= s. 899 // This is a copy of sort.Search, with f(h) replaced by (t.nameOff(methods[h].name).name() >= name). 900 i, j := 0, len(methods) 901 for i < j { 902 h := int(uint(i+j) >> 1) // avoid overflow when computing h 903 // i ≤ h < j 904 if !(t.nameOff(methods[h].name).name() >= name) { 905 i = h + 1 // preserves f(i-1) == false 906 } else { 907 j = h // preserves f(j) == true 908 } 909 } 910 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 911 if i < len(methods) && name == t.nameOff(methods[i].name).name() { 912 return t.Method(i), true 913 } 914 915 return Method{}, false 916 } 917 918 func (t *rtype) PkgPath() string { 919 if t.tflag&tflagNamed == 0 { 920 return "" 921 } 922 ut := t.uncommon() 923 if ut == nil { 924 return "" 925 } 926 return t.nameOff(ut.pkgPath).name() 927 } 928 929 func (t *rtype) hasName() bool { 930 return t.tflag&tflagNamed != 0 931 } 932 933 func (t *rtype) Name() string { 934 if !t.hasName() { 935 return "" 936 } 937 s := t.String() 938 i := len(s) - 1 939 sqBrackets := 0 940 for i >= 0 && (s[i] != '.' || sqBrackets != 0) { 941 switch s[i] { 942 case ']': 943 sqBrackets++ 944 case '[': 945 sqBrackets-- 946 } 947 i-- 948 } 949 return s[i+1:] 950 } 951 952 func (t *rtype) ChanDir() ChanDir { 953 if t.Kind() != Chan { 954 panic("reflect: ChanDir of non-chan type " + t.String()) 955 } 956 tt := (*chanType)(unsafe.Pointer(t)) 957 return ChanDir(tt.dir) 958 } 959 960 func (t *rtype) IsVariadic() bool { 961 if t.Kind() != Func { 962 panic("reflect: IsVariadic of non-func type " + t.String()) 963 } 964 tt := (*funcType)(unsafe.Pointer(t)) 965 return tt.outCount&(1<<15) != 0 966 } 967 968 func (t *rtype) Elem() Type { 969 switch t.Kind() { 970 case Array: 971 tt := (*arrayType)(unsafe.Pointer(t)) 972 return toType(tt.elem) 973 case Chan: 974 tt := (*chanType)(unsafe.Pointer(t)) 975 return toType(tt.elem) 976 case Map: 977 tt := (*mapType)(unsafe.Pointer(t)) 978 return toType(tt.elem) 979 case Pointer: 980 tt := (*ptrType)(unsafe.Pointer(t)) 981 return toType(tt.elem) 982 case Slice: 983 tt := (*sliceType)(unsafe.Pointer(t)) 984 return toType(tt.elem) 985 } 986 panic("reflect: Elem of invalid type " + t.String()) 987 } 988 989 func (t *rtype) Field(i int) StructField { 990 if t.Kind() != Struct { 991 panic("reflect: Field of non-struct type " + t.String()) 992 } 993 tt := (*structType)(unsafe.Pointer(t)) 994 return tt.Field(i) 995 } 996 997 func (t *rtype) FieldByIndex(index []int) StructField { 998 if t.Kind() != Struct { 999 panic("reflect: FieldByIndex of non-struct type " + t.String()) 1000 } 1001 tt := (*structType)(unsafe.Pointer(t)) 1002 return tt.FieldByIndex(index) 1003 } 1004 1005 func (t *rtype) FieldByName(name string) (StructField, bool) { 1006 if t.Kind() != Struct { 1007 panic("reflect: FieldByName of non-struct type " + t.String()) 1008 } 1009 tt := (*structType)(unsafe.Pointer(t)) 1010 return tt.FieldByName(name) 1011 } 1012 1013 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 1014 if t.Kind() != Struct { 1015 panic("reflect: FieldByNameFunc of non-struct type " + t.String()) 1016 } 1017 tt := (*structType)(unsafe.Pointer(t)) 1018 return tt.FieldByNameFunc(match) 1019 } 1020 1021 func (t *rtype) In(i int) Type { 1022 if t.Kind() != Func { 1023 panic("reflect: In of non-func type " + t.String()) 1024 } 1025 tt := (*funcType)(unsafe.Pointer(t)) 1026 return toType(tt.in()[i]) 1027 } 1028 1029 func (t *rtype) Key() Type { 1030 if t.Kind() != Map { 1031 panic("reflect: Key of non-map type " + t.String()) 1032 } 1033 tt := (*mapType)(unsafe.Pointer(t)) 1034 return toType(tt.key) 1035 } 1036 1037 func (t *rtype) Len() int { 1038 if t.Kind() != Array { 1039 panic("reflect: Len of non-array type " + t.String()) 1040 } 1041 tt := (*arrayType)(unsafe.Pointer(t)) 1042 return int(tt.len) 1043 } 1044 1045 func (t *rtype) NumField() int { 1046 if t.Kind() != Struct { 1047 panic("reflect: NumField of non-struct type " + t.String()) 1048 } 1049 tt := (*structType)(unsafe.Pointer(t)) 1050 return len(tt.fields) 1051 } 1052 1053 func (t *rtype) NumIn() int { 1054 if t.Kind() != Func { 1055 panic("reflect: NumIn of non-func type " + t.String()) 1056 } 1057 tt := (*funcType)(unsafe.Pointer(t)) 1058 return int(tt.inCount) 1059 } 1060 1061 func (t *rtype) NumOut() int { 1062 if t.Kind() != Func { 1063 panic("reflect: NumOut of non-func type " + t.String()) 1064 } 1065 tt := (*funcType)(unsafe.Pointer(t)) 1066 return len(tt.out()) 1067 } 1068 1069 func (t *rtype) Out(i int) Type { 1070 if t.Kind() != Func { 1071 panic("reflect: Out of non-func type " + t.String()) 1072 } 1073 tt := (*funcType)(unsafe.Pointer(t)) 1074 return toType(tt.out()[i]) 1075 } 1076 1077 func (t *funcType) in() []*rtype { 1078 uadd := unsafe.Sizeof(*t) 1079 if t.tflag&tflagUncommon != 0 { 1080 uadd += unsafe.Sizeof(uncommonType{}) 1081 } 1082 if t.inCount == 0 { 1083 return nil 1084 } 1085 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount] 1086 } 1087 1088 func (t *funcType) out() []*rtype { 1089 uadd := unsafe.Sizeof(*t) 1090 if t.tflag&tflagUncommon != 0 { 1091 uadd += unsafe.Sizeof(uncommonType{}) 1092 } 1093 outCount := t.outCount & (1<<15 - 1) 1094 if outCount == 0 { 1095 return nil 1096 } 1097 return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount] 1098 } 1099 1100 // add returns p+x. 1101 // 1102 // The whySafe string is ignored, so that the function still inlines 1103 // as efficiently as p+x, but all call sites should use the string to 1104 // record why the addition is safe, which is to say why the addition 1105 // does not cause x to advance to the very end of p's allocation 1106 // and therefore point incorrectly at the next block in memory. 1107 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 1108 return unsafe.Pointer(uintptr(p) + x) 1109 } 1110 1111 func (d ChanDir) String() string { 1112 switch d { 1113 case SendDir: 1114 return "chan<-" 1115 case RecvDir: 1116 return "<-chan" 1117 case BothDir: 1118 return "chan" 1119 } 1120 return "ChanDir" + strconv.Itoa(int(d)) 1121 } 1122 1123 // Method returns the i'th method in the type's method set. 1124 func (t *interfaceType) Method(i int) (m Method) { 1125 if i < 0 || i >= len(t.methods) { 1126 return 1127 } 1128 p := &t.methods[i] 1129 pname := t.nameOff(p.name) 1130 m.Name = pname.name() 1131 if !pname.isExported() { 1132 m.PkgPath = pname.pkgPath() 1133 if m.PkgPath == "" { 1134 m.PkgPath = t.pkgPath.name() 1135 } 1136 } 1137 m.Type = toType(t.typeOff(p.typ)) 1138 m.Index = i 1139 return 1140 } 1141 1142 // NumMethod returns the number of interface methods in the type's method set. 1143 func (t *interfaceType) NumMethod() int { return len(t.methods) } 1144 1145 // MethodByName method with the given name in the type's method set. 1146 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) { 1147 if t == nil { 1148 return 1149 } 1150 var p *imethod 1151 for i := range t.methods { 1152 p = &t.methods[i] 1153 if t.nameOff(p.name).name() == name { 1154 return t.Method(i), true 1155 } 1156 } 1157 return 1158 } 1159 1160 // A StructField describes a single field in a struct. 1161 type StructField struct { 1162 // Name is the field name. 1163 Name string 1164 1165 // PkgPath is the package path that qualifies a lower case (unexported) 1166 // field name. It is empty for upper case (exported) field names. 1167 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 1168 PkgPath string 1169 1170 Type Type // field type 1171 Tag StructTag // field tag string 1172 Offset uintptr // offset within struct, in bytes 1173 Index []int // index sequence for Type.FieldByIndex 1174 Anonymous bool // is an embedded field 1175 } 1176 1177 // IsExported reports whether the field is exported. 1178 func (f StructField) IsExported() bool { 1179 return f.PkgPath == "" 1180 } 1181 1182 // A StructTag is the tag string in a struct field. 1183 // 1184 // By convention, tag strings are a concatenation of 1185 // optionally space-separated key:"value" pairs. 1186 // Each key is a non-empty string consisting of non-control 1187 // characters other than space (U+0020 ' '), quote (U+0022 '"'), 1188 // and colon (U+003A ':'). Each value is quoted using U+0022 '"' 1189 // characters and Go string literal syntax. 1190 type StructTag string 1191 1192 // Get returns the value associated with key in the tag string. 1193 // If there is no such key in the tag, Get returns the empty string. 1194 // If the tag does not have the conventional format, the value 1195 // returned by Get is unspecified. To determine whether a tag is 1196 // explicitly set to the empty string, use Lookup. 1197 func (tag StructTag) Get(key string) string { 1198 v, _ := tag.Lookup(key) 1199 return v 1200 } 1201 1202 // Lookup returns the value associated with key in the tag string. 1203 // If the key is present in the tag the value (which may be empty) 1204 // is returned. Otherwise the returned value will be the empty string. 1205 // The ok return value reports whether the value was explicitly set in 1206 // the tag string. If the tag does not have the conventional format, 1207 // the value returned by Lookup is unspecified. 1208 func (tag StructTag) Lookup(key string) (value string, ok bool) { 1209 // When modifying this code, also update the validateStructTag code 1210 // in cmd/vet/structtag.go. 1211 1212 for tag != "" { 1213 // Skip leading space. 1214 i := 0 1215 for i < len(tag) && tag[i] == ' ' { 1216 i++ 1217 } 1218 tag = tag[i:] 1219 if tag == "" { 1220 break 1221 } 1222 1223 // Scan to colon. A space, a quote or a control character is a syntax error. 1224 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just 1225 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters 1226 // as it is simpler to inspect the tag's bytes than the tag's runes. 1227 i = 0 1228 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { 1229 i++ 1230 } 1231 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 1232 break 1233 } 1234 name := string(tag[:i]) 1235 tag = tag[i+1:] 1236 1237 // Scan quoted string to find value. 1238 i = 1 1239 for i < len(tag) && tag[i] != '"' { 1240 if tag[i] == '\\' { 1241 i++ 1242 } 1243 i++ 1244 } 1245 if i >= len(tag) { 1246 break 1247 } 1248 qvalue := string(tag[:i+1]) 1249 tag = tag[i+1:] 1250 1251 if key == name { 1252 value, err := strconv.Unquote(qvalue) 1253 if err != nil { 1254 break 1255 } 1256 return value, true 1257 } 1258 } 1259 return "", false 1260 } 1261 1262 // Field returns the i'th struct field. 1263 func (t *structType) Field(i int) (f StructField) { 1264 if i < 0 || i >= len(t.fields) { 1265 panic("reflect: Field index out of bounds") 1266 } 1267 p := &t.fields[i] 1268 f.Type = toType(p.typ) 1269 f.Name = p.name.name() 1270 f.Anonymous = p.embedded() 1271 if !p.name.isExported() { 1272 f.PkgPath = t.pkgPath.name() 1273 } 1274 if tag := p.name.tag(); tag != "" { 1275 f.Tag = StructTag(tag) 1276 } 1277 f.Offset = p.offset 1278 1279 // NOTE(rsc): This is the only allocation in the interface 1280 // presented by a reflect.Type. It would be nice to avoid, 1281 // at least in the common cases, but we need to make sure 1282 // that misbehaving clients of reflect cannot affect other 1283 // uses of reflect. One possibility is CL 5371098, but we 1284 // postponed that ugliness until there is a demonstrated 1285 // need for the performance. This is issue 2320. 1286 f.Index = []int{i} 1287 return 1288 } 1289 1290 // TODO(gri): Should there be an error/bool indicator if the index 1291 // is wrong for FieldByIndex? 1292 1293 // FieldByIndex returns the nested field corresponding to index. 1294 func (t *structType) FieldByIndex(index []int) (f StructField) { 1295 f.Type = toType(&t.rtype) 1296 for i, x := range index { 1297 if i > 0 { 1298 ft := f.Type 1299 if ft.Kind() == Pointer && ft.Elem().Kind() == Struct { 1300 ft = ft.Elem() 1301 } 1302 f.Type = ft 1303 } 1304 f = f.Type.Field(x) 1305 } 1306 return 1307 } 1308 1309 // A fieldScan represents an item on the fieldByNameFunc scan work list. 1310 type fieldScan struct { 1311 typ *structType 1312 index []int 1313 } 1314 1315 // FieldByNameFunc returns the struct field with a name that satisfies the 1316 // match function and a boolean to indicate if the field was found. 1317 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) { 1318 // This uses the same condition that the Go language does: there must be a unique instance 1319 // of the match at a given depth level. If there are multiple instances of a match at the 1320 // same depth, they annihilate each other and inhibit any possible match at a lower level. 1321 // The algorithm is breadth first search, one depth level at a time. 1322 1323 // The current and next slices are work queues: 1324 // current lists the fields to visit on this depth level, 1325 // and next lists the fields on the next lower level. 1326 current := []fieldScan{} 1327 next := []fieldScan{{typ: t}} 1328 1329 // nextCount records the number of times an embedded type has been 1330 // encountered and considered for queueing in the 'next' slice. 1331 // We only queue the first one, but we increment the count on each. 1332 // If a struct type T can be reached more than once at a given depth level, 1333 // then it annihilates itself and need not be considered at all when we 1334 // process that next depth level. 1335 var nextCount map[*structType]int 1336 1337 // visited records the structs that have been considered already. 1338 // Embedded pointer fields can create cycles in the graph of 1339 // reachable embedded types; visited avoids following those cycles. 1340 // It also avoids duplicated effort: if we didn't find the field in an 1341 // embedded type T at level 2, we won't find it in one at level 4 either. 1342 visited := map[*structType]bool{} 1343 1344 for len(next) > 0 { 1345 current, next = next, current[:0] 1346 count := nextCount 1347 nextCount = nil 1348 1349 // Process all the fields at this depth, now listed in 'current'. 1350 // The loop queues embedded fields found in 'next', for processing during the next 1351 // iteration. The multiplicity of the 'current' field counts is recorded 1352 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. 1353 for _, scan := range current { 1354 t := scan.typ 1355 if visited[t] { 1356 // We've looked through this type before, at a higher level. 1357 // That higher level would shadow the lower level we're now at, 1358 // so this one can't be useful to us. Ignore it. 1359 continue 1360 } 1361 visited[t] = true 1362 for i := range t.fields { 1363 f := &t.fields[i] 1364 // Find name and (for embedded field) type for field f. 1365 fname := f.name.name() 1366 var ntyp *rtype 1367 if f.embedded() { 1368 // Embedded field of type T or *T. 1369 ntyp = f.typ 1370 if ntyp.Kind() == Pointer { 1371 ntyp = ntyp.Elem().common() 1372 } 1373 } 1374 1375 // Does it match? 1376 if match(fname) { 1377 // Potential match 1378 if count[t] > 1 || ok { 1379 // Name appeared multiple times at this level: annihilate. 1380 return StructField{}, false 1381 } 1382 result = t.Field(i) 1383 result.Index = nil 1384 result.Index = append(result.Index, scan.index...) 1385 result.Index = append(result.Index, i) 1386 ok = true 1387 continue 1388 } 1389 1390 // Queue embedded struct fields for processing with next level, 1391 // but only if we haven't seen a match yet at this level and only 1392 // if the embedded types haven't already been queued. 1393 if ok || ntyp == nil || ntyp.Kind() != Struct { 1394 continue 1395 } 1396 styp := (*structType)(unsafe.Pointer(ntyp)) 1397 if nextCount[styp] > 0 { 1398 nextCount[styp] = 2 // exact multiple doesn't matter 1399 continue 1400 } 1401 if nextCount == nil { 1402 nextCount = map[*structType]int{} 1403 } 1404 nextCount[styp] = 1 1405 if count[t] > 1 { 1406 nextCount[styp] = 2 // exact multiple doesn't matter 1407 } 1408 var index []int 1409 index = append(index, scan.index...) 1410 index = append(index, i) 1411 next = append(next, fieldScan{styp, index}) 1412 } 1413 } 1414 if ok { 1415 break 1416 } 1417 } 1418 return 1419 } 1420 1421 // FieldByName returns the struct field with the given name 1422 // and a boolean to indicate if the field was found. 1423 func (t *structType) FieldByName(name string) (f StructField, present bool) { 1424 // Quick check for top-level name, or struct without embedded fields. 1425 hasEmbeds := false 1426 if name != "" { 1427 for i := range t.fields { 1428 tf := &t.fields[i] 1429 if tf.name.name() == name { 1430 return t.Field(i), true 1431 } 1432 if tf.embedded() { 1433 hasEmbeds = true 1434 } 1435 } 1436 } 1437 if !hasEmbeds { 1438 return 1439 } 1440 return t.FieldByNameFunc(func(s string) bool { return s == name }) 1441 } 1442 1443 // TypeOf returns the reflection Type that represents the dynamic type of i. 1444 // If i is a nil interface value, TypeOf returns nil. 1445 func TypeOf(i any) Type { 1446 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1447 return toType(eface.typ) 1448 } 1449 1450 // rtypeOf directly extracts the *rtype of the provided value. 1451 func rtypeOf(i any) *rtype { 1452 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1453 return eface.typ 1454 } 1455 1456 // ptrMap is the cache for PointerTo. 1457 var ptrMap sync.Map // map[*rtype]*ptrType 1458 1459 // PtrTo returns the pointer type with element t. 1460 // For example, if t represents type Foo, PtrTo(t) represents *Foo. 1461 // 1462 // PtrTo is the old spelling of PointerTo. 1463 // The two functions behave identically. 1464 func PtrTo(t Type) Type { return PointerTo(t) } 1465 1466 // PointerTo returns the pointer type with element t. 1467 // For example, if t represents type Foo, PointerTo(t) represents *Foo. 1468 func PointerTo(t Type) Type { 1469 return t.(*rtype).ptrTo() 1470 } 1471 1472 func (t *rtype) ptrTo() *rtype { 1473 if t.ptrToThis != 0 { 1474 return t.typeOff(t.ptrToThis) 1475 } 1476 1477 // Check the cache. 1478 if pi, ok := ptrMap.Load(t); ok { 1479 return &pi.(*ptrType).rtype 1480 } 1481 1482 // Look in known types. 1483 s := "*" + t.String() 1484 for _, tt := range typesByString(s) { 1485 p := (*ptrType)(unsafe.Pointer(tt)) 1486 if p.elem != t { 1487 continue 1488 } 1489 pi, _ := ptrMap.LoadOrStore(t, p) 1490 return &pi.(*ptrType).rtype 1491 } 1492 1493 // Create a new ptrType starting with the description 1494 // of an *unsafe.Pointer. 1495 var iptr any = (*unsafe.Pointer)(nil) 1496 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 1497 pp := *prototype 1498 1499 pp.str = resolveReflectName(newName(s, "", false, false)) 1500 pp.ptrToThis = 0 1501 1502 // For the type structures linked into the binary, the 1503 // compiler provides a good hash of the string. 1504 // Create a good hash for the new string by using 1505 // the FNV-1 hash's mixing function to combine the 1506 // old hash and the new "*". 1507 pp.hash = fnv1(t.hash, '*') 1508 1509 pp.elem = t 1510 1511 pi, _ := ptrMap.LoadOrStore(t, &pp) 1512 return &pi.(*ptrType).rtype 1513 } 1514 1515 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 1516 func fnv1(x uint32, list ...byte) uint32 { 1517 for _, b := range list { 1518 x = x*16777619 ^ uint32(b) 1519 } 1520 return x 1521 } 1522 1523 func (t *rtype) Implements(u Type) bool { 1524 if u == nil { 1525 panic("reflect: nil type passed to Type.Implements") 1526 } 1527 if u.Kind() != Interface { 1528 panic("reflect: non-interface type passed to Type.Implements") 1529 } 1530 return implements(u.(*rtype), t) 1531 } 1532 1533 func (t *rtype) AssignableTo(u Type) bool { 1534 if u == nil { 1535 panic("reflect: nil type passed to Type.AssignableTo") 1536 } 1537 uu := u.(*rtype) 1538 return directlyAssignable(uu, t) || implements(uu, t) 1539 } 1540 1541 func (t *rtype) ConvertibleTo(u Type) bool { 1542 if u == nil { 1543 panic("reflect: nil type passed to Type.ConvertibleTo") 1544 } 1545 uu := u.(*rtype) 1546 return convertOp(uu, t) != nil 1547 } 1548 1549 func (t *rtype) Comparable() bool { 1550 return t.equal != nil 1551 } 1552 1553 // implements reports whether the type V implements the interface type T. 1554 func implements(T, V *rtype) bool { 1555 if T.Kind() != Interface { 1556 return false 1557 } 1558 t := (*interfaceType)(unsafe.Pointer(T)) 1559 if len(t.methods) == 0 { 1560 return true 1561 } 1562 1563 // The same algorithm applies in both cases, but the 1564 // method tables for an interface type and a concrete type 1565 // are different, so the code is duplicated. 1566 // In both cases the algorithm is a linear scan over the two 1567 // lists - T's methods and V's methods - simultaneously. 1568 // Since method tables are stored in a unique sorted order 1569 // (alphabetical, with no duplicate method names), the scan 1570 // through V's methods must hit a match for each of T's 1571 // methods along the way, or else V does not implement T. 1572 // This lets us run the scan in overall linear time instead of 1573 // the quadratic time a naive search would require. 1574 // See also ../runtime/iface.go. 1575 if V.Kind() == Interface { 1576 v := (*interfaceType)(unsafe.Pointer(V)) 1577 i := 0 1578 for j := 0; j < len(v.methods); j++ { 1579 tm := &t.methods[i] 1580 tmName := t.nameOff(tm.name) 1581 vm := &v.methods[j] 1582 vmName := V.nameOff(vm.name) 1583 if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) { 1584 if !tmName.isExported() { 1585 tmPkgPath := tmName.pkgPath() 1586 if tmPkgPath == "" { 1587 tmPkgPath = t.pkgPath.name() 1588 } 1589 vmPkgPath := vmName.pkgPath() 1590 if vmPkgPath == "" { 1591 vmPkgPath = v.pkgPath.name() 1592 } 1593 if tmPkgPath != vmPkgPath { 1594 continue 1595 } 1596 } 1597 if i++; i >= len(t.methods) { 1598 return true 1599 } 1600 } 1601 } 1602 return false 1603 } 1604 1605 v := V.uncommon() 1606 if v == nil { 1607 return false 1608 } 1609 i := 0 1610 vmethods := v.methods() 1611 for j := 0; j < int(v.mcount); j++ { 1612 tm := &t.methods[i] 1613 tmName := t.nameOff(tm.name) 1614 vm := vmethods[j] 1615 vmName := V.nameOff(vm.name) 1616 if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) { 1617 if !tmName.isExported() { 1618 tmPkgPath := tmName.pkgPath() 1619 if tmPkgPath == "" { 1620 tmPkgPath = t.pkgPath.name() 1621 } 1622 vmPkgPath := vmName.pkgPath() 1623 if vmPkgPath == "" { 1624 vmPkgPath = V.nameOff(v.pkgPath).name() 1625 } 1626 if tmPkgPath != vmPkgPath { 1627 continue 1628 } 1629 } 1630 if i++; i >= len(t.methods) { 1631 return true 1632 } 1633 } 1634 } 1635 return false 1636 } 1637 1638 // specialChannelAssignability reports whether a value x of channel type V 1639 // can be directly assigned (using memmove) to another channel type T. 1640 // https://golang.org/doc/go_spec.html#Assignability 1641 // T and V must be both of Chan kind. 1642 func specialChannelAssignability(T, V *rtype) bool { 1643 // Special case: 1644 // x is a bidirectional channel value, T is a channel type, 1645 // x's type V and T have identical element types, 1646 // and at least one of V or T is not a defined type. 1647 return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true) 1648 } 1649 1650 // directlyAssignable reports whether a value x of type V can be directly 1651 // assigned (using memmove) to a value of type T. 1652 // https://golang.org/doc/go_spec.html#Assignability 1653 // Ignoring the interface rules (implemented elsewhere) 1654 // and the ideal constant rules (no ideal constants at run time). 1655 func directlyAssignable(T, V *rtype) bool { 1656 // x's type V is identical to T? 1657 if T == V { 1658 return true 1659 } 1660 1661 // Otherwise at least one of T and V must not be defined 1662 // and they must have the same kind. 1663 if T.hasName() && V.hasName() || T.Kind() != V.Kind() { 1664 return false 1665 } 1666 1667 if T.Kind() == Chan && specialChannelAssignability(T, V) { 1668 return true 1669 } 1670 1671 // x's type T and V must have identical underlying types. 1672 return haveIdenticalUnderlyingType(T, V, true) 1673 } 1674 1675 func haveIdenticalType(T, V Type, cmpTags bool) bool { 1676 if cmpTags { 1677 return T == V 1678 } 1679 1680 if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() { 1681 return false 1682 } 1683 1684 return haveIdenticalUnderlyingType(T.common(), V.common(), false) 1685 } 1686 1687 func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { 1688 if T == V { 1689 return true 1690 } 1691 1692 kind := T.Kind() 1693 if kind != V.Kind() { 1694 return false 1695 } 1696 1697 // Non-composite types of equal kind have same underlying type 1698 // (the predefined instance of the type). 1699 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 1700 return true 1701 } 1702 1703 // Composite types. 1704 switch kind { 1705 case Array: 1706 return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1707 1708 case Chan: 1709 return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1710 1711 case Func: 1712 t := (*funcType)(unsafe.Pointer(T)) 1713 v := (*funcType)(unsafe.Pointer(V)) 1714 if t.outCount != v.outCount || t.inCount != v.inCount { 1715 return false 1716 } 1717 for i := 0; i < t.NumIn(); i++ { 1718 if !haveIdenticalType(t.In(i), v.In(i), cmpTags) { 1719 return false 1720 } 1721 } 1722 for i := 0; i < t.NumOut(); i++ { 1723 if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) { 1724 return false 1725 } 1726 } 1727 return true 1728 1729 case Interface: 1730 t := (*interfaceType)(unsafe.Pointer(T)) 1731 v := (*interfaceType)(unsafe.Pointer(V)) 1732 if len(t.methods) == 0 && len(v.methods) == 0 { 1733 return true 1734 } 1735 // Might have the same methods but still 1736 // need a run time conversion. 1737 return false 1738 1739 case Map: 1740 return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1741 1742 case Pointer, Slice: 1743 return haveIdenticalType(T.Elem(), V.Elem(), cmpTags) 1744 1745 case Struct: 1746 t := (*structType)(unsafe.Pointer(T)) 1747 v := (*structType)(unsafe.Pointer(V)) 1748 if len(t.fields) != len(v.fields) { 1749 return false 1750 } 1751 if t.pkgPath.name() != v.pkgPath.name() { 1752 return false 1753 } 1754 for i := range t.fields { 1755 tf := &t.fields[i] 1756 vf := &v.fields[i] 1757 if tf.name.name() != vf.name.name() { 1758 return false 1759 } 1760 if !haveIdenticalType(tf.typ, vf.typ, cmpTags) { 1761 return false 1762 } 1763 if cmpTags && tf.name.tag() != vf.name.tag() { 1764 return false 1765 } 1766 if tf.offset != vf.offset { 1767 return false 1768 } 1769 if tf.embedded() != vf.embedded() { 1770 return false 1771 } 1772 } 1773 return true 1774 } 1775 1776 return false 1777 } 1778 1779 // typelinks is implemented in package runtime. 1780 // It returns a slice of the sections in each module, 1781 // and a slice of *rtype offsets in each module. 1782 // 1783 // The types in each module are sorted by string. That is, the first 1784 // two linked types of the first module are: 1785 // 1786 // d0 := sections[0] 1787 // t1 := (*rtype)(add(d0, offset[0][0])) 1788 // t2 := (*rtype)(add(d0, offset[0][1])) 1789 // 1790 // and 1791 // 1792 // t1.String() < t2.String() 1793 // 1794 // Note that strings are not unique identifiers for types: 1795 // there can be more than one with a given string. 1796 // Only types we might want to look up are included: 1797 // pointers, channels, maps, slices, and arrays. 1798 func typelinks() (sections []unsafe.Pointer, offset [][]int32) 1799 1800 func rtypeOff(section unsafe.Pointer, off int32) *rtype { 1801 return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0")) 1802 } 1803 1804 // typesByString returns the subslice of typelinks() whose elements have 1805 // the given string representation. 1806 // It may be empty (no known types with that string) or may have 1807 // multiple elements (multiple types with that string). 1808 func typesByString(s string) []*rtype { 1809 sections, offset := typelinks() 1810 var ret []*rtype 1811 1812 for offsI, offs := range offset { 1813 section := sections[offsI] 1814 1815 // We are looking for the first index i where the string becomes >= s. 1816 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s). 1817 i, j := 0, len(offs) 1818 for i < j { 1819 h := i + (j-i)>>1 // avoid overflow when computing h 1820 // i ≤ h < j 1821 if !(rtypeOff(section, offs[h]).String() >= s) { 1822 i = h + 1 // preserves f(i-1) == false 1823 } else { 1824 j = h // preserves f(j) == true 1825 } 1826 } 1827 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 1828 1829 // Having found the first, linear scan forward to find the last. 1830 // We could do a second binary search, but the caller is going 1831 // to do a linear scan anyway. 1832 for j := i; j < len(offs); j++ { 1833 typ := rtypeOff(section, offs[j]) 1834 if typ.String() != s { 1835 break 1836 } 1837 ret = append(ret, typ) 1838 } 1839 } 1840 return ret 1841 } 1842 1843 // The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups. 1844 var lookupCache sync.Map // map[cacheKey]*rtype 1845 1846 // A cacheKey is the key for use in the lookupCache. 1847 // Four values describe any of the types we are looking for: 1848 // type kind, one or two subtypes, and an extra integer. 1849 type cacheKey struct { 1850 kind Kind 1851 t1 *rtype 1852 t2 *rtype 1853 extra uintptr 1854 } 1855 1856 // The funcLookupCache caches FuncOf lookups. 1857 // FuncOf does not share the common lookupCache since cacheKey is not 1858 // sufficient to represent functions unambiguously. 1859 var funcLookupCache struct { 1860 sync.Mutex // Guards stores (but not loads) on m. 1861 1862 // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf. 1863 // Elements of m are append-only and thus safe for concurrent reading. 1864 m sync.Map 1865 } 1866 1867 // ChanOf returns the channel type with the given direction and element type. 1868 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int. 1869 // 1870 // The gc runtime imposes a limit of 64 kB on channel element types. 1871 // If t's size is equal to or exceeds this limit, ChanOf panics. 1872 func ChanOf(dir ChanDir, t Type) Type { 1873 typ := t.(*rtype) 1874 1875 // Look in cache. 1876 ckey := cacheKey{Chan, typ, nil, uintptr(dir)} 1877 if ch, ok := lookupCache.Load(ckey); ok { 1878 return ch.(*rtype) 1879 } 1880 1881 // This restriction is imposed by the gc compiler and the runtime. 1882 if typ.size >= 1<<16 { 1883 panic("reflect.ChanOf: element size too large") 1884 } 1885 1886 // Look in known types. 1887 var s string 1888 switch dir { 1889 default: 1890 panic("reflect.ChanOf: invalid dir") 1891 case SendDir: 1892 s = "chan<- " + typ.String() 1893 case RecvDir: 1894 s = "<-chan " + typ.String() 1895 case BothDir: 1896 typeStr := typ.String() 1897 if typeStr[0] == '<' { 1898 // typ is recv chan, need parentheses as "<-" associates with leftmost 1899 // chan possible, see: 1900 // * https://golang.org/ref/spec#Channel_types 1901 // * https://github.com/golang/go/issues/39897 1902 s = "chan (" + typeStr + ")" 1903 } else { 1904 s = "chan " + typeStr 1905 } 1906 } 1907 for _, tt := range typesByString(s) { 1908 ch := (*chanType)(unsafe.Pointer(tt)) 1909 if ch.elem == typ && ch.dir == uintptr(dir) { 1910 ti, _ := lookupCache.LoadOrStore(ckey, tt) 1911 return ti.(Type) 1912 } 1913 } 1914 1915 // Make a channel type. 1916 var ichan any = (chan unsafe.Pointer)(nil) 1917 prototype := *(**chanType)(unsafe.Pointer(&ichan)) 1918 ch := *prototype 1919 ch.tflag = tflagRegularMemory 1920 ch.dir = uintptr(dir) 1921 ch.str = resolveReflectName(newName(s, "", false, false)) 1922 ch.hash = fnv1(typ.hash, 'c', byte(dir)) 1923 ch.elem = typ 1924 1925 ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype) 1926 return ti.(Type) 1927 } 1928 1929 // MapOf returns the map type with the given key and element types. 1930 // For example, if k represents int and e represents string, 1931 // MapOf(k, e) represents map[int]string. 1932 // 1933 // If the key type is not a valid map key type (that is, if it does 1934 // not implement Go's == operator), MapOf panics. 1935 func MapOf(key, elem Type) Type { 1936 ktyp := key.(*rtype) 1937 etyp := elem.(*rtype) 1938 1939 if ktyp.equal == nil { 1940 panic("reflect.MapOf: invalid key type " + ktyp.String()) 1941 } 1942 1943 // Look in cache. 1944 ckey := cacheKey{Map, ktyp, etyp, 0} 1945 if mt, ok := lookupCache.Load(ckey); ok { 1946 return mt.(Type) 1947 } 1948 1949 // Look in known types. 1950 s := "map[" + ktyp.String() + "]" + etyp.String() 1951 for _, tt := range typesByString(s) { 1952 mt := (*mapType)(unsafe.Pointer(tt)) 1953 if mt.key == ktyp && mt.elem == etyp { 1954 ti, _ := lookupCache.LoadOrStore(ckey, tt) 1955 return ti.(Type) 1956 } 1957 } 1958 1959 // Make a map type. 1960 // Note: flag values must match those used in the TMAP case 1961 // in ../cmd/compile/internal/reflectdata/reflect.go:writeType. 1962 var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil) 1963 mt := **(**mapType)(unsafe.Pointer(&imap)) 1964 mt.str = resolveReflectName(newName(s, "", false, false)) 1965 mt.tflag = 0 1966 mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash)) 1967 mt.key = ktyp 1968 mt.elem = etyp 1969 mt.bucket = bucketOf(ktyp, etyp) 1970 mt.hasher = func(p unsafe.Pointer, seed uintptr) uintptr { 1971 return typehash(ktyp, p, seed) 1972 } 1973 mt.flags = 0 1974 if ktyp.size > maxKeySize { 1975 mt.keysize = uint8(goarch.PtrSize) 1976 mt.flags |= 1 // indirect key 1977 } else { 1978 mt.keysize = uint8(ktyp.size) 1979 } 1980 if etyp.size > maxValSize { 1981 mt.valuesize = uint8(goarch.PtrSize) 1982 mt.flags |= 2 // indirect value 1983 } else { 1984 mt.valuesize = uint8(etyp.size) 1985 } 1986 mt.bucketsize = uint16(mt.bucket.size) 1987 if isReflexive(ktyp) { 1988 mt.flags |= 4 1989 } 1990 if needKeyUpdate(ktyp) { 1991 mt.flags |= 8 1992 } 1993 if hashMightPanic(ktyp) { 1994 mt.flags |= 16 1995 } 1996 mt.ptrToThis = 0 1997 1998 ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype) 1999 return ti.(Type) 2000 } 2001 2002 var funcTypes []Type 2003 var funcTypesMutex sync.Mutex 2004 2005 func initFuncTypes(n int) Type { 2006 funcTypesMutex.Lock() 2007 defer funcTypesMutex.Unlock() 2008 if n >= len(funcTypes) { 2009 newFuncTypes := make([]Type, n+1) 2010 copy(newFuncTypes, funcTypes) 2011 funcTypes = newFuncTypes 2012 } 2013 if funcTypes[n] != nil { 2014 return funcTypes[n] 2015 } 2016 2017 funcTypes[n] = StructOf([]StructField{ 2018 { 2019 Name: "FuncType", 2020 Type: TypeOf(funcType{}), 2021 }, 2022 { 2023 Name: "Args", 2024 Type: ArrayOf(n, TypeOf(&rtype{})), 2025 }, 2026 }) 2027 return funcTypes[n] 2028 } 2029 2030 // FuncOf returns the function type with the given argument and result types. 2031 // For example if k represents int and e represents string, 2032 // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string. 2033 // 2034 // The variadic argument controls whether the function is variadic. FuncOf 2035 // panics if the in[len(in)-1] does not represent a slice and variadic is 2036 // true. 2037 func FuncOf(in, out []Type, variadic bool) Type { 2038 if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) { 2039 panic("reflect.FuncOf: last arg of variadic func must be slice") 2040 } 2041 2042 // Make a func type. 2043 var ifunc any = (func())(nil) 2044 prototype := *(**funcType)(unsafe.Pointer(&ifunc)) 2045 n := len(in) + len(out) 2046 2047 if n > 128 { 2048 panic("reflect.FuncOf: too many arguments") 2049 } 2050 2051 o := New(initFuncTypes(n)).Elem() 2052 ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer())) 2053 args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n] 2054 *ft = *prototype 2055 2056 // Build a hash and minimally populate ft. 2057 var hash uint32 2058 for _, in := range in { 2059 t := in.(*rtype) 2060 args = append(args, t) 2061 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 2062 } 2063 if variadic { 2064 hash = fnv1(hash, 'v') 2065 } 2066 hash = fnv1(hash, '.') 2067 for _, out := range out { 2068 t := out.(*rtype) 2069 args = append(args, t) 2070 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 2071 } 2072 2073 ft.tflag = 0 2074 ft.hash = hash 2075 ft.inCount = uint16(len(in)) 2076 ft.outCount = uint16(len(out)) 2077 if variadic { 2078 ft.outCount |= 1 << 15 2079 } 2080 2081 // Look in cache. 2082 if ts, ok := funcLookupCache.m.Load(hash); ok { 2083 for _, t := range ts.([]*rtype) { 2084 if haveIdenticalUnderlyingType(&ft.rtype, t, true) { 2085 return t 2086 } 2087 } 2088 } 2089 2090 // Not in cache, lock and retry. 2091 funcLookupCache.Lock() 2092 defer funcLookupCache.Unlock() 2093 if ts, ok := funcLookupCache.m.Load(hash); ok { 2094 for _, t := range ts.([]*rtype) { 2095 if haveIdenticalUnderlyingType(&ft.rtype, t, true) { 2096 return t 2097 } 2098 } 2099 } 2100 2101 addToCache := func(tt *rtype) Type { 2102 var rts []*rtype 2103 if rti, ok := funcLookupCache.m.Load(hash); ok { 2104 rts = rti.([]*rtype) 2105 } 2106 funcLookupCache.m.Store(hash, append(rts, tt)) 2107 return tt 2108 } 2109 2110 // Look in known types for the same string representation. 2111 str := funcStr(ft) 2112 for _, tt := range typesByString(str) { 2113 if haveIdenticalUnderlyingType(&ft.rtype, tt, true) { 2114 return addToCache(tt) 2115 } 2116 } 2117 2118 // Populate the remaining fields of ft and store in cache. 2119 ft.str = resolveReflectName(newName(str, "", false, false)) 2120 ft.ptrToThis = 0 2121 return addToCache(&ft.rtype) 2122 } 2123 2124 // funcStr builds a string representation of a funcType. 2125 func funcStr(ft *funcType) string { 2126 repr := make([]byte, 0, 64) 2127 repr = append(repr, "func("...) 2128 for i, t := range ft.in() { 2129 if i > 0 { 2130 repr = append(repr, ", "...) 2131 } 2132 if ft.IsVariadic() && i == int(ft.inCount)-1 { 2133 repr = append(repr, "..."...) 2134 repr = append(repr, (*sliceType)(unsafe.Pointer(t)).elem.String()...) 2135 } else { 2136 repr = append(repr, t.String()...) 2137 } 2138 } 2139 repr = append(repr, ')') 2140 out := ft.out() 2141 if len(out) == 1 { 2142 repr = append(repr, ' ') 2143 } else if len(out) > 1 { 2144 repr = append(repr, " ("...) 2145 } 2146 for i, t := range out { 2147 if i > 0 { 2148 repr = append(repr, ", "...) 2149 } 2150 repr = append(repr, t.String()...) 2151 } 2152 if len(out) > 1 { 2153 repr = append(repr, ')') 2154 } 2155 return string(repr) 2156 } 2157 2158 // isReflexive reports whether the == operation on the type is reflexive. 2159 // That is, x == x for all values x of type t. 2160 func isReflexive(t *rtype) bool { 2161 switch t.Kind() { 2162 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, String, UnsafePointer: 2163 return true 2164 case Float32, Float64, Complex64, Complex128, Interface: 2165 return false 2166 case Array: 2167 tt := (*arrayType)(unsafe.Pointer(t)) 2168 return isReflexive(tt.elem) 2169 case Struct: 2170 tt := (*structType)(unsafe.Pointer(t)) 2171 for _, f := range tt.fields { 2172 if !isReflexive(f.typ) { 2173 return false 2174 } 2175 } 2176 return true 2177 default: 2178 // Func, Map, Slice, Invalid 2179 panic("isReflexive called on non-key type " + t.String()) 2180 } 2181 } 2182 2183 // needKeyUpdate reports whether map overwrites require the key to be copied. 2184 func needKeyUpdate(t *rtype) bool { 2185 switch t.Kind() { 2186 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, UnsafePointer: 2187 return false 2188 case Float32, Float64, Complex64, Complex128, Interface, String: 2189 // Float keys can be updated from +0 to -0. 2190 // String keys can be updated to use a smaller backing store. 2191 // Interfaces might have floats of strings in them. 2192 return true 2193 case Array: 2194 tt := (*arrayType)(unsafe.Pointer(t)) 2195 return needKeyUpdate(tt.elem) 2196 case Struct: 2197 tt := (*structType)(unsafe.Pointer(t)) 2198 for _, f := range tt.fields { 2199 if needKeyUpdate(f.typ) { 2200 return true 2201 } 2202 } 2203 return false 2204 default: 2205 // Func, Map, Slice, Invalid 2206 panic("needKeyUpdate called on non-key type " + t.String()) 2207 } 2208 } 2209 2210 // hashMightPanic reports whether the hash of a map key of type t might panic. 2211 func hashMightPanic(t *rtype) bool { 2212 switch t.Kind() { 2213 case Interface: 2214 return true 2215 case Array: 2216 tt := (*arrayType)(unsafe.Pointer(t)) 2217 return hashMightPanic(tt.elem) 2218 case Struct: 2219 tt := (*structType)(unsafe.Pointer(t)) 2220 for _, f := range tt.fields { 2221 if hashMightPanic(f.typ) { 2222 return true 2223 } 2224 } 2225 return false 2226 default: 2227 return false 2228 } 2229 } 2230 2231 // Make sure these routines stay in sync with ../runtime/map.go! 2232 // These types exist only for GC, so we only fill out GC relevant info. 2233 // Currently, that's just size and the GC program. We also fill in string 2234 // for possible debugging use. 2235 const ( 2236 bucketSize uintptr = 8 2237 maxKeySize uintptr = 128 2238 maxValSize uintptr = 128 2239 ) 2240 2241 func bucketOf(ktyp, etyp *rtype) *rtype { 2242 if ktyp.size > maxKeySize { 2243 ktyp = PointerTo(ktyp).(*rtype) 2244 } 2245 if etyp.size > maxValSize { 2246 etyp = PointerTo(etyp).(*rtype) 2247 } 2248 2249 // Prepare GC data if any. 2250 // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+ptrSize bytes, 2251 // or 2064 bytes, or 258 pointer-size words, or 33 bytes of pointer bitmap. 2252 // Note that since the key and value are known to be <= 128 bytes, 2253 // they're guaranteed to have bitmaps instead of GC programs. 2254 var gcdata *byte 2255 var ptrdata uintptr 2256 2257 size := bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize 2258 if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 { 2259 panic("reflect: bad size computation in MapOf") 2260 } 2261 2262 if ktyp.ptrdata != 0 || etyp.ptrdata != 0 { 2263 nptr := (bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize) / goarch.PtrSize 2264 n := (nptr + 7) / 8 2265 // Runtime needs pointer masks to be a multiple of uintptr in size. 2266 n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1) 2267 mask := make([]byte, n) 2268 base := bucketSize / goarch.PtrSize 2269 2270 if ktyp.ptrdata != 0 { 2271 emitGCMask(mask, base, ktyp, bucketSize) 2272 } 2273 base += bucketSize * ktyp.size / goarch.PtrSize 2274 2275 if etyp.ptrdata != 0 { 2276 emitGCMask(mask, base, etyp, bucketSize) 2277 } 2278 base += bucketSize * etyp.size / goarch.PtrSize 2279 2280 word := base 2281 mask[word/8] |= 1 << (word % 8) 2282 gcdata = &mask[0] 2283 ptrdata = (word + 1) * goarch.PtrSize 2284 2285 // overflow word must be last 2286 if ptrdata != size { 2287 panic("reflect: bad layout computation in MapOf") 2288 } 2289 } 2290 2291 b := &rtype{ 2292 align: goarch.PtrSize, 2293 size: size, 2294 kind: uint8(Struct), 2295 ptrdata: ptrdata, 2296 gcdata: gcdata, 2297 } 2298 s := "bucket(" + ktyp.String() + "," + etyp.String() + ")" 2299 b.str = resolveReflectName(newName(s, "", false, false)) 2300 return b 2301 } 2302 2303 func (t *rtype) gcSlice(begin, end uintptr) []byte { 2304 return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end] 2305 } 2306 2307 // emitGCMask writes the GC mask for [n]typ into out, starting at bit 2308 // offset base. 2309 func emitGCMask(out []byte, base uintptr, typ *rtype, n uintptr) { 2310 if typ.kind&kindGCProg != 0 { 2311 panic("reflect: unexpected GC program") 2312 } 2313 ptrs := typ.ptrdata / goarch.PtrSize 2314 words := typ.size / goarch.PtrSize 2315 mask := typ.gcSlice(0, (ptrs+7)/8) 2316 for j := uintptr(0); j < ptrs; j++ { 2317 if (mask[j/8]>>(j%8))&1 != 0 { 2318 for i := uintptr(0); i < n; i++ { 2319 k := base + i*words + j 2320 out[k/8] |= 1 << (k % 8) 2321 } 2322 } 2323 } 2324 } 2325 2326 // appendGCProg appends the GC program for the first ptrdata bytes of 2327 // typ to dst and returns the extended slice. 2328 func appendGCProg(dst []byte, typ *rtype) []byte { 2329 if typ.kind&kindGCProg != 0 { 2330 // Element has GC program; emit one element. 2331 n := uintptr(*(*uint32)(unsafe.Pointer(typ.gcdata))) 2332 prog := typ.gcSlice(4, 4+n-1) 2333 return append(dst, prog...) 2334 } 2335 2336 // Element is small with pointer mask; use as literal bits. 2337 ptrs := typ.ptrdata / goarch.PtrSize 2338 mask := typ.gcSlice(0, (ptrs+7)/8) 2339 2340 // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). 2341 for ; ptrs > 120; ptrs -= 120 { 2342 dst = append(dst, 120) 2343 dst = append(dst, mask[:15]...) 2344 mask = mask[15:] 2345 } 2346 2347 dst = append(dst, byte(ptrs)) 2348 dst = append(dst, mask...) 2349 return dst 2350 } 2351 2352 // SliceOf returns the slice type with element type t. 2353 // For example, if t represents int, SliceOf(t) represents []int. 2354 func SliceOf(t Type) Type { 2355 typ := t.(*rtype) 2356 2357 // Look in cache. 2358 ckey := cacheKey{Slice, typ, nil, 0} 2359 if slice, ok := lookupCache.Load(ckey); ok { 2360 return slice.(Type) 2361 } 2362 2363 // Look in known types. 2364 s := "[]" + typ.String() 2365 for _, tt := range typesByString(s) { 2366 slice := (*sliceType)(unsafe.Pointer(tt)) 2367 if slice.elem == typ { 2368 ti, _ := lookupCache.LoadOrStore(ckey, tt) 2369 return ti.(Type) 2370 } 2371 } 2372 2373 // Make a slice type. 2374 var islice any = ([]unsafe.Pointer)(nil) 2375 prototype := *(**sliceType)(unsafe.Pointer(&islice)) 2376 slice := *prototype 2377 slice.tflag = 0 2378 slice.str = resolveReflectName(newName(s, "", false, false)) 2379 slice.hash = fnv1(typ.hash, '[') 2380 slice.elem = typ 2381 slice.ptrToThis = 0 2382 2383 ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype) 2384 return ti.(Type) 2385 } 2386 2387 // The structLookupCache caches StructOf lookups. 2388 // StructOf does not share the common lookupCache since we need to pin 2389 // the memory associated with *structTypeFixedN. 2390 var structLookupCache struct { 2391 sync.Mutex // Guards stores (but not loads) on m. 2392 2393 // m is a map[uint32][]Type keyed by the hash calculated in StructOf. 2394 // Elements in m are append-only and thus safe for concurrent reading. 2395 m sync.Map 2396 } 2397 2398 type structTypeUncommon struct { 2399 structType 2400 u uncommonType 2401 } 2402 2403 // isLetter reports whether a given 'rune' is classified as a Letter. 2404 func isLetter(ch rune) bool { 2405 return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch) 2406 } 2407 2408 // isValidFieldName checks if a string is a valid (struct) field name or not. 2409 // 2410 // According to the language spec, a field name should be an identifier. 2411 // 2412 // identifier = letter { letter | unicode_digit } . 2413 // letter = unicode_letter | "_" . 2414 func isValidFieldName(fieldName string) bool { 2415 for i, c := range fieldName { 2416 if i == 0 && !isLetter(c) { 2417 return false 2418 } 2419 2420 if !(isLetter(c) || unicode.IsDigit(c)) { 2421 return false 2422 } 2423 } 2424 2425 return len(fieldName) > 0 2426 } 2427 2428 // StructOf returns the struct type containing fields. 2429 // The Offset and Index fields are ignored and computed as they would be 2430 // by the compiler. 2431 // 2432 // StructOf currently does not generate wrapper methods for embedded 2433 // fields and panics if passed unexported StructFields. 2434 // These limitations may be lifted in a future version. 2435 func StructOf(fields []StructField) Type { 2436 var ( 2437 hash = fnv1(0, []byte("struct {")...) 2438 size uintptr 2439 typalign uint8 2440 comparable = true 2441 methods []method 2442 2443 fs = make([]structField, len(fields)) 2444 repr = make([]byte, 0, 64) 2445 fset = map[string]struct{}{} // fields' names 2446 2447 hasGCProg = false // records whether a struct-field type has a GCProg 2448 ) 2449 2450 lastzero := uintptr(0) 2451 repr = append(repr, "struct {"...) 2452 pkgpath := "" 2453 for i, field := range fields { 2454 if field.Name == "" { 2455 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name") 2456 } 2457 if !isValidFieldName(field.Name) { 2458 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name") 2459 } 2460 if field.Type == nil { 2461 panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type") 2462 } 2463 f, fpkgpath := runtimeStructField(field) 2464 ft := f.typ 2465 if ft.kind&kindGCProg != 0 { 2466 hasGCProg = true 2467 } 2468 if fpkgpath != "" { 2469 if pkgpath == "" { 2470 pkgpath = fpkgpath 2471 } else if pkgpath != fpkgpath { 2472 panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath) 2473 } 2474 } 2475 2476 // Update string and hash 2477 name := f.name.name() 2478 hash = fnv1(hash, []byte(name)...) 2479 repr = append(repr, (" " + name)...) 2480 if f.embedded() { 2481 // Embedded field 2482 if f.typ.Kind() == Pointer { 2483 // Embedded ** and *interface{} are illegal 2484 elem := ft.Elem() 2485 if k := elem.Kind(); k == Pointer || k == Interface { 2486 panic("reflect.StructOf: illegal embedded field type " + ft.String()) 2487 } 2488 } 2489 2490 switch f.typ.Kind() { 2491 case Interface: 2492 ift := (*interfaceType)(unsafe.Pointer(ft)) 2493 for im, m := range ift.methods { 2494 if ift.nameOff(m.name).pkgPath() != "" { 2495 // TODO(sbinet). Issue 15924. 2496 panic("reflect: embedded interface with unexported method(s) not implemented") 2497 } 2498 2499 var ( 2500 mtyp = ift.typeOff(m.typ) 2501 ifield = i 2502 imethod = im 2503 ifn Value 2504 tfn Value 2505 ) 2506 2507 if ft.kind&kindDirectIface != 0 { 2508 tfn = MakeFunc(mtyp, func(in []Value) []Value { 2509 var args []Value 2510 var recv = in[0] 2511 if len(in) > 1 { 2512 args = in[1:] 2513 } 2514 return recv.Field(ifield).Method(imethod).Call(args) 2515 }) 2516 ifn = MakeFunc(mtyp, func(in []Value) []Value { 2517 var args []Value 2518 var recv = in[0] 2519 if len(in) > 1 { 2520 args = in[1:] 2521 } 2522 return recv.Field(ifield).Method(imethod).Call(args) 2523 }) 2524 } else { 2525 tfn = MakeFunc(mtyp, func(in []Value) []Value { 2526 var args []Value 2527 var recv = in[0] 2528 if len(in) > 1 { 2529 args = in[1:] 2530 } 2531 return recv.Field(ifield).Method(imethod).Call(args) 2532 }) 2533 ifn = MakeFunc(mtyp, func(in []Value) []Value { 2534 var args []Value 2535 var recv = Indirect(in[0]) 2536 if len(in) > 1 { 2537 args = in[1:] 2538 } 2539 return recv.Field(ifield).Method(imethod).Call(args) 2540 }) 2541 } 2542 2543 methods = append(methods, method{ 2544 name: resolveReflectName(ift.nameOff(m.name)), 2545 mtyp: resolveReflectType(mtyp), 2546 ifn: resolveReflectText(unsafe.Pointer(&ifn)), 2547 tfn: resolveReflectText(unsafe.Pointer(&tfn)), 2548 }) 2549 } 2550 case Pointer: 2551 ptr := (*ptrType)(unsafe.Pointer(ft)) 2552 if unt := ptr.uncommon(); unt != nil { 2553 if i > 0 && unt.mcount > 0 { 2554 // Issue 15924. 2555 panic("reflect: embedded type with methods not implemented if type is not first field") 2556 } 2557 if len(fields) > 1 { 2558 panic("reflect: embedded type with methods not implemented if there is more than one field") 2559 } 2560 for _, m := range unt.methods() { 2561 mname := ptr.nameOff(m.name) 2562 if mname.pkgPath() != "" { 2563 // TODO(sbinet). 2564 // Issue 15924. 2565 panic("reflect: embedded interface with unexported method(s) not implemented") 2566 } 2567 methods = append(methods, method{ 2568 name: resolveReflectName(mname), 2569 mtyp: resolveReflectType(ptr.typeOff(m.mtyp)), 2570 ifn: resolveReflectText(ptr.textOff(m.ifn)), 2571 tfn: resolveReflectText(ptr.textOff(m.tfn)), 2572 }) 2573 } 2574 } 2575 if unt := ptr.elem.uncommon(); unt != nil { 2576 for _, m := range unt.methods() { 2577 mname := ptr.nameOff(m.name) 2578 if mname.pkgPath() != "" { 2579 // TODO(sbinet) 2580 // Issue 15924. 2581 panic("reflect: embedded interface with unexported method(s) not implemented") 2582 } 2583 methods = append(methods, method{ 2584 name: resolveReflectName(mname), 2585 mtyp: resolveReflectType(ptr.elem.typeOff(m.mtyp)), 2586 ifn: resolveReflectText(ptr.elem.textOff(m.ifn)), 2587 tfn: resolveReflectText(ptr.elem.textOff(m.tfn)), 2588 }) 2589 } 2590 } 2591 default: 2592 if unt := ft.uncommon(); unt != nil { 2593 if i > 0 && unt.mcount > 0 { 2594 // Issue 15924. 2595 panic("reflect: embedded type with methods not implemented if type is not first field") 2596 } 2597 if len(fields) > 1 && ft.kind&kindDirectIface != 0 { 2598 panic("reflect: embedded type with methods not implemented for non-pointer type") 2599 } 2600 for _, m := range unt.methods() { 2601 mname := ft.nameOff(m.name) 2602 if mname.pkgPath() != "" { 2603 // TODO(sbinet) 2604 // Issue 15924. 2605 panic("reflect: embedded interface with unexported method(s) not implemented") 2606 } 2607 methods = append(methods, method{ 2608 name: resolveReflectName(mname), 2609 mtyp: resolveReflectType(ft.typeOff(m.mtyp)), 2610 ifn: resolveReflectText(ft.textOff(m.ifn)), 2611 tfn: resolveReflectText(ft.textOff(m.tfn)), 2612 }) 2613 2614 } 2615 } 2616 } 2617 } 2618 if _, dup := fset[name]; dup && name != "_" { 2619 panic("reflect.StructOf: duplicate field " + name) 2620 } 2621 fset[name] = struct{}{} 2622 2623 hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash)) 2624 2625 repr = append(repr, (" " + ft.String())...) 2626 if f.name.hasTag() { 2627 hash = fnv1(hash, []byte(f.name.tag())...) 2628 repr = append(repr, (" " + strconv.Quote(f.name.tag()))...) 2629 } 2630 if i < len(fields)-1 { 2631 repr = append(repr, ';') 2632 } 2633 2634 comparable = comparable && (ft.equal != nil) 2635 2636 offset := align(size, uintptr(ft.align)) 2637 if offset < size { 2638 panic("reflect.StructOf: struct size would exceed virtual address space") 2639 } 2640 if ft.align > typalign { 2641 typalign = ft.align 2642 } 2643 size = offset + ft.size 2644 if size < offset { 2645 panic("reflect.StructOf: struct size would exceed virtual address space") 2646 } 2647 f.offset = offset 2648 2649 if ft.size == 0 { 2650 lastzero = size 2651 } 2652 2653 fs[i] = f 2654 } 2655 2656 if size > 0 && lastzero == size { 2657 // This is a non-zero sized struct that ends in a 2658 // zero-sized field. We add an extra byte of padding, 2659 // to ensure that taking the address of the final 2660 // zero-sized field can't manufacture a pointer to the 2661 // next object in the heap. See issue 9401. 2662 size++ 2663 if size == 0 { 2664 panic("reflect.StructOf: struct size would exceed virtual address space") 2665 } 2666 } 2667 2668 var typ *structType 2669 var ut *uncommonType 2670 2671 if len(methods) == 0 { 2672 t := new(structTypeUncommon) 2673 typ = &t.structType 2674 ut = &t.u 2675 } else { 2676 // A *rtype representing a struct is followed directly in memory by an 2677 // array of method objects representing the methods attached to the 2678 // struct. To get the same layout for a run time generated type, we 2679 // need an array directly following the uncommonType memory. 2680 // A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN. 2681 tt := New(StructOf([]StructField{ 2682 {Name: "S", Type: TypeOf(structType{})}, 2683 {Name: "U", Type: TypeOf(uncommonType{})}, 2684 {Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))}, 2685 })) 2686 2687 typ = (*structType)(tt.Elem().Field(0).Addr().UnsafePointer()) 2688 ut = (*uncommonType)(tt.Elem().Field(1).Addr().UnsafePointer()) 2689 2690 copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]method), methods) 2691 } 2692 // TODO(sbinet): Once we allow embedding multiple types, 2693 // methods will need to be sorted like the compiler does. 2694 // TODO(sbinet): Once we allow non-exported methods, we will 2695 // need to compute xcount as the number of exported methods. 2696 ut.mcount = uint16(len(methods)) 2697 ut.xcount = ut.mcount 2698 ut.moff = uint32(unsafe.Sizeof(uncommonType{})) 2699 2700 if len(fs) > 0 { 2701 repr = append(repr, ' ') 2702 } 2703 repr = append(repr, '}') 2704 hash = fnv1(hash, '}') 2705 str := string(repr) 2706 2707 // Round the size up to be a multiple of the alignment. 2708 s := align(size, uintptr(typalign)) 2709 if s < size { 2710 panic("reflect.StructOf: struct size would exceed virtual address space") 2711 } 2712 size = s 2713 2714 // Make the struct type. 2715 var istruct any = struct{}{} 2716 prototype := *(**structType)(unsafe.Pointer(&istruct)) 2717 *typ = *prototype 2718 typ.fields = fs 2719 if pkgpath != "" { 2720 typ.pkgPath = newName(pkgpath, "", false, false) 2721 } 2722 2723 // Look in cache. 2724 if ts, ok := structLookupCache.m.Load(hash); ok { 2725 for _, st := range ts.([]Type) { 2726 t := st.common() 2727 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2728 return t 2729 } 2730 } 2731 } 2732 2733 // Not in cache, lock and retry. 2734 structLookupCache.Lock() 2735 defer structLookupCache.Unlock() 2736 if ts, ok := structLookupCache.m.Load(hash); ok { 2737 for _, st := range ts.([]Type) { 2738 t := st.common() 2739 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2740 return t 2741 } 2742 } 2743 } 2744 2745 addToCache := func(t Type) Type { 2746 var ts []Type 2747 if ti, ok := structLookupCache.m.Load(hash); ok { 2748 ts = ti.([]Type) 2749 } 2750 structLookupCache.m.Store(hash, append(ts, t)) 2751 return t 2752 } 2753 2754 // Look in known types. 2755 for _, t := range typesByString(str) { 2756 if haveIdenticalUnderlyingType(&typ.rtype, t, true) { 2757 // even if 't' wasn't a structType with methods, we should be ok 2758 // as the 'u uncommonType' field won't be accessed except when 2759 // tflag&tflagUncommon is set. 2760 return addToCache(t) 2761 } 2762 } 2763 2764 typ.str = resolveReflectName(newName(str, "", false, false)) 2765 typ.tflag = 0 // TODO: set tflagRegularMemory 2766 typ.hash = hash 2767 typ.size = size 2768 typ.ptrdata = typeptrdata(typ.common()) 2769 typ.align = typalign 2770 typ.fieldAlign = typalign 2771 typ.ptrToThis = 0 2772 if len(methods) > 0 { 2773 typ.tflag |= tflagUncommon 2774 } 2775 2776 if hasGCProg { 2777 lastPtrField := 0 2778 for i, ft := range fs { 2779 if ft.typ.pointers() { 2780 lastPtrField = i 2781 } 2782 } 2783 prog := []byte{0, 0, 0, 0} // will be length of prog 2784 var off uintptr 2785 for i, ft := range fs { 2786 if i > lastPtrField { 2787 // gcprog should not include anything for any field after 2788 // the last field that contains pointer data 2789 break 2790 } 2791 if !ft.typ.pointers() { 2792 // Ignore pointerless fields. 2793 continue 2794 } 2795 // Pad to start of this field with zeros. 2796 if ft.offset > off { 2797 n := (ft.offset - off) / goarch.PtrSize 2798 prog = append(prog, 0x01, 0x00) // emit a 0 bit 2799 if n > 1 { 2800 prog = append(prog, 0x81) // repeat previous bit 2801 prog = appendVarint(prog, n-1) // n-1 times 2802 } 2803 off = ft.offset 2804 } 2805 2806 prog = appendGCProg(prog, ft.typ) 2807 off += ft.typ.ptrdata 2808 } 2809 prog = append(prog, 0) 2810 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4) 2811 typ.kind |= kindGCProg 2812 typ.gcdata = &prog[0] 2813 } else { 2814 typ.kind &^= kindGCProg 2815 bv := new(bitVector) 2816 addTypeBits(bv, 0, typ.common()) 2817 if len(bv.data) > 0 { 2818 typ.gcdata = &bv.data[0] 2819 } 2820 } 2821 typ.equal = nil 2822 if comparable { 2823 typ.equal = func(p, q unsafe.Pointer) bool { 2824 for _, ft := range typ.fields { 2825 pi := add(p, ft.offset, "&x.field safe") 2826 qi := add(q, ft.offset, "&x.field safe") 2827 if !ft.typ.equal(pi, qi) { 2828 return false 2829 } 2830 } 2831 return true 2832 } 2833 } 2834 2835 switch { 2836 case len(fs) == 1 && !ifaceIndir(fs[0].typ): 2837 // structs of 1 direct iface type can be direct 2838 typ.kind |= kindDirectIface 2839 default: 2840 typ.kind &^= kindDirectIface 2841 } 2842 2843 return addToCache(&typ.rtype) 2844 } 2845 2846 // runtimeStructField takes a StructField value passed to StructOf and 2847 // returns both the corresponding internal representation, of type 2848 // structField, and the pkgpath value to use for this field. 2849 func runtimeStructField(field StructField) (structField, string) { 2850 if field.Anonymous && field.PkgPath != "" { 2851 panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set") 2852 } 2853 2854 if field.IsExported() { 2855 // Best-effort check for misuse. 2856 // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through. 2857 c := field.Name[0] 2858 if 'a' <= c && c <= 'z' || c == '_' { 2859 panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath") 2860 } 2861 } 2862 2863 resolveReflectType(field.Type.common()) // install in runtime 2864 f := structField{ 2865 name: newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous), 2866 typ: field.Type.common(), 2867 offset: 0, 2868 } 2869 return f, field.PkgPath 2870 } 2871 2872 // typeptrdata returns the length in bytes of the prefix of t 2873 // containing pointer data. Anything after this offset is scalar data. 2874 // keep in sync with ../cmd/compile/internal/reflectdata/reflect.go 2875 func typeptrdata(t *rtype) uintptr { 2876 switch t.Kind() { 2877 case Struct: 2878 st := (*structType)(unsafe.Pointer(t)) 2879 // find the last field that has pointers. 2880 field := -1 2881 for i := range st.fields { 2882 ft := st.fields[i].typ 2883 if ft.pointers() { 2884 field = i 2885 } 2886 } 2887 if field == -1 { 2888 return 0 2889 } 2890 f := st.fields[field] 2891 return f.offset + f.typ.ptrdata 2892 2893 default: 2894 panic("reflect.typeptrdata: unexpected type, " + t.String()) 2895 } 2896 } 2897 2898 // See cmd/compile/internal/reflectdata/reflect.go for derivation of constant. 2899 const maxPtrmaskBytes = 2048 2900 2901 // ArrayOf returns the array type with the given length and element type. 2902 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 2903 // 2904 // If the resulting type would be larger than the available address space, 2905 // ArrayOf panics. 2906 func ArrayOf(length int, elem Type) Type { 2907 if length < 0 { 2908 panic("reflect: negative length passed to ArrayOf") 2909 } 2910 2911 typ := elem.(*rtype) 2912 2913 // Look in cache. 2914 ckey := cacheKey{Array, typ, nil, uintptr(length)} 2915 if array, ok := lookupCache.Load(ckey); ok { 2916 return array.(Type) 2917 } 2918 2919 // Look in known types. 2920 s := "[" + strconv.Itoa(length) + "]" + typ.String() 2921 for _, tt := range typesByString(s) { 2922 array := (*arrayType)(unsafe.Pointer(tt)) 2923 if array.elem == typ { 2924 ti, _ := lookupCache.LoadOrStore(ckey, tt) 2925 return ti.(Type) 2926 } 2927 } 2928 2929 // Make an array type. 2930 var iarray any = [1]unsafe.Pointer{} 2931 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 2932 array := *prototype 2933 array.tflag = typ.tflag & tflagRegularMemory 2934 array.str = resolveReflectName(newName(s, "", false, false)) 2935 array.hash = fnv1(typ.hash, '[') 2936 for n := uint32(length); n > 0; n >>= 8 { 2937 array.hash = fnv1(array.hash, byte(n)) 2938 } 2939 array.hash = fnv1(array.hash, ']') 2940 array.elem = typ 2941 array.ptrToThis = 0 2942 if typ.size > 0 { 2943 max := ^uintptr(0) / typ.size 2944 if uintptr(length) > max { 2945 panic("reflect.ArrayOf: array size would exceed virtual address space") 2946 } 2947 } 2948 array.size = typ.size * uintptr(length) 2949 if length > 0 && typ.ptrdata != 0 { 2950 array.ptrdata = typ.size*uintptr(length-1) + typ.ptrdata 2951 } 2952 array.align = typ.align 2953 array.fieldAlign = typ.fieldAlign 2954 array.len = uintptr(length) 2955 array.slice = SliceOf(elem).(*rtype) 2956 2957 switch { 2958 case typ.ptrdata == 0 || array.size == 0: 2959 // No pointers. 2960 array.gcdata = nil 2961 array.ptrdata = 0 2962 2963 case length == 1: 2964 // In memory, 1-element array looks just like the element. 2965 array.kind |= typ.kind & kindGCProg 2966 array.gcdata = typ.gcdata 2967 array.ptrdata = typ.ptrdata 2968 2969 case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*goarch.PtrSize: 2970 // Element is small with pointer mask; array is still small. 2971 // Create direct pointer mask by turning each 1 bit in elem 2972 // into length 1 bits in larger mask. 2973 n := (array.ptrdata/goarch.PtrSize + 7) / 8 2974 // Runtime needs pointer masks to be a multiple of uintptr in size. 2975 n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1) 2976 mask := make([]byte, n) 2977 emitGCMask(mask, 0, typ, array.len) 2978 array.gcdata = &mask[0] 2979 2980 default: 2981 // Create program that emits one element 2982 // and then repeats to make the array. 2983 prog := []byte{0, 0, 0, 0} // will be length of prog 2984 prog = appendGCProg(prog, typ) 2985 // Pad from ptrdata to size. 2986 elemPtrs := typ.ptrdata / goarch.PtrSize 2987 elemWords := typ.size / goarch.PtrSize 2988 if elemPtrs < elemWords { 2989 // Emit literal 0 bit, then repeat as needed. 2990 prog = append(prog, 0x01, 0x00) 2991 if elemPtrs+1 < elemWords { 2992 prog = append(prog, 0x81) 2993 prog = appendVarint(prog, elemWords-elemPtrs-1) 2994 } 2995 } 2996 // Repeat length-1 times. 2997 if elemWords < 0x80 { 2998 prog = append(prog, byte(elemWords|0x80)) 2999 } else { 3000 prog = append(prog, 0x80) 3001 prog = appendVarint(prog, elemWords) 3002 } 3003 prog = appendVarint(prog, uintptr(length)-1) 3004 prog = append(prog, 0) 3005 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4) 3006 array.kind |= kindGCProg 3007 array.gcdata = &prog[0] 3008 array.ptrdata = array.size // overestimate but ok; must match program 3009 } 3010 3011 etyp := typ.common() 3012 esize := etyp.Size() 3013 3014 array.equal = nil 3015 if eequal := etyp.equal; eequal != nil { 3016 array.equal = func(p, q unsafe.Pointer) bool { 3017 for i := 0; i < length; i++ { 3018 pi := arrayAt(p, i, esize, "i < length") 3019 qi := arrayAt(q, i, esize, "i < length") 3020 if !eequal(pi, qi) { 3021 return false 3022 } 3023 3024 } 3025 return true 3026 } 3027 } 3028 3029 switch { 3030 case length == 1 && !ifaceIndir(typ): 3031 // array of 1 direct iface type can be direct 3032 array.kind |= kindDirectIface 3033 default: 3034 array.kind &^= kindDirectIface 3035 } 3036 3037 ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype) 3038 return ti.(Type) 3039 } 3040 3041 func appendVarint(x []byte, v uintptr) []byte { 3042 for ; v >= 0x80; v >>= 7 { 3043 x = append(x, byte(v|0x80)) 3044 } 3045 x = append(x, byte(v)) 3046 return x 3047 } 3048 3049 // toType converts from a *rtype to a Type that can be returned 3050 // to the client of package reflect. In gc, the only concern is that 3051 // a nil *rtype must be replaced by a nil Type, but in gccgo this 3052 // function takes care of ensuring that multiple *rtype for the same 3053 // type are coalesced into a single Type. 3054 func toType(t *rtype) Type { 3055 if t == nil { 3056 return nil 3057 } 3058 return t 3059 } 3060 3061 type layoutKey struct { 3062 ftyp *funcType // function signature 3063 rcvr *rtype // receiver type, or nil if none 3064 } 3065 3066 type layoutType struct { 3067 t *rtype 3068 framePool *sync.Pool 3069 abid abiDesc 3070 } 3071 3072 var layoutCache sync.Map // map[layoutKey]layoutType 3073 3074 // funcLayout computes a struct type representing the layout of the 3075 // stack-assigned function arguments and return values for the function 3076 // type t. 3077 // If rcvr != nil, rcvr specifies the type of the receiver. 3078 // The returned type exists only for GC, so we only fill out GC relevant info. 3079 // Currently, that's just size and the GC program. We also fill in 3080 // the name for possible debugging use. 3081 func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abid abiDesc) { 3082 if t.Kind() != Func { 3083 panic("reflect: funcLayout of non-func type " + t.String()) 3084 } 3085 if rcvr != nil && rcvr.Kind() == Interface { 3086 panic("reflect: funcLayout with interface receiver " + rcvr.String()) 3087 } 3088 k := layoutKey{t, rcvr} 3089 if lti, ok := layoutCache.Load(k); ok { 3090 lt := lti.(layoutType) 3091 return lt.t, lt.framePool, lt.abid 3092 } 3093 3094 // Compute the ABI layout. 3095 abid = newAbiDesc(t, rcvr) 3096 3097 // build dummy rtype holding gc program 3098 x := &rtype{ 3099 align: goarch.PtrSize, 3100 // Don't add spill space here; it's only necessary in 3101 // reflectcall's frame, not in the allocated frame. 3102 // TODO(mknyszek): Remove this comment when register 3103 // spill space in the frame is no longer required. 3104 size: align(abid.retOffset+abid.ret.stackBytes, goarch.PtrSize), 3105 ptrdata: uintptr(abid.stackPtrs.n) * goarch.PtrSize, 3106 } 3107 if abid.stackPtrs.n > 0 { 3108 x.gcdata = &abid.stackPtrs.data[0] 3109 } 3110 3111 var s string 3112 if rcvr != nil { 3113 s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")" 3114 } else { 3115 s = "funcargs(" + t.String() + ")" 3116 } 3117 x.str = resolveReflectName(newName(s, "", false, false)) 3118 3119 // cache result for future callers 3120 framePool = &sync.Pool{New: func() any { 3121 return unsafe_New(x) 3122 }} 3123 lti, _ := layoutCache.LoadOrStore(k, layoutType{ 3124 t: x, 3125 framePool: framePool, 3126 abid: abid, 3127 }) 3128 lt := lti.(layoutType) 3129 return lt.t, lt.framePool, lt.abid 3130 } 3131 3132 // ifaceIndir reports whether t is stored indirectly in an interface value. 3133 func ifaceIndir(t *rtype) bool { 3134 return t.kind&kindDirectIface == 0 3135 } 3136 3137 // Note: this type must agree with runtime.bitvector. 3138 type bitVector struct { 3139 n uint32 // number of bits 3140 data []byte 3141 } 3142 3143 // append a bit to the bitmap. 3144 func (bv *bitVector) append(bit uint8) { 3145 if bv.n%(8*goarch.PtrSize) == 0 { 3146 // Runtime needs pointer masks to be a multiple of uintptr in size. 3147 // Since reflect passes bv.data directly to the runtime as a pointer mask, 3148 // we append a full uintptr of zeros at a time. 3149 for i := 0; i < goarch.PtrSize; i++ { 3150 bv.data = append(bv.data, 0) 3151 } 3152 } 3153 bv.data[bv.n/8] |= bit << (bv.n % 8) 3154 bv.n++ 3155 } 3156 3157 func addTypeBits(bv *bitVector, offset uintptr, t *rtype) { 3158 if t.ptrdata == 0 { 3159 return 3160 } 3161 3162 switch Kind(t.kind & kindMask) { 3163 case Chan, Func, Map, Pointer, Slice, String, UnsafePointer: 3164 // 1 pointer at start of representation 3165 for bv.n < uint32(offset/uintptr(goarch.PtrSize)) { 3166 bv.append(0) 3167 } 3168 bv.append(1) 3169 3170 case Interface: 3171 // 2 pointers 3172 for bv.n < uint32(offset/uintptr(goarch.PtrSize)) { 3173 bv.append(0) 3174 } 3175 bv.append(1) 3176 bv.append(1) 3177 3178 case Array: 3179 // repeat inner type 3180 tt := (*arrayType)(unsafe.Pointer(t)) 3181 for i := 0; i < int(tt.len); i++ { 3182 addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem) 3183 } 3184 3185 case Struct: 3186 // apply fields 3187 tt := (*structType)(unsafe.Pointer(t)) 3188 for i := range tt.fields { 3189 f := &tt.fields[i] 3190 addTypeBits(bv, offset+f.offset, f.typ) 3191 } 3192 } 3193 }