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