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