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