github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/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 // rtype is the common implementation of most values. 244 // It is embedded in other, public struct types, but always 245 // with a unique tag like `reflect:"array"` or `reflect:"ptr"` 246 // so that code cannot convert from, say, *arrayType to *ptrType. 247 type rtype struct { 248 size uintptr 249 ptrdata uintptr 250 hash uint32 // hash of type; avoids computation in hash tables 251 _ uint8 // unused/padding 252 align uint8 // alignment of variable with this type 253 fieldAlign uint8 // alignment of struct field with this type 254 kind uint8 // enumeration for C 255 alg *typeAlg // algorithm table 256 gcdata *byte // garbage collection data 257 string *string // string form; unnecessary but undeniably useful 258 *uncommonType // (relatively) uncommon fields 259 ptrToThis *rtype // type for pointer to this type, if used in binary or has methods 260 } 261 262 // a copy of runtime.typeAlg 263 type typeAlg struct { 264 // function for hashing objects of this type 265 // (ptr to object, seed) -> hash 266 hash func(unsafe.Pointer, uintptr) uintptr 267 // function for comparing objects of this type 268 // (ptr to object A, ptr to object B) -> ==? 269 equal func(unsafe.Pointer, unsafe.Pointer) bool 270 } 271 272 // Method on non-interface type 273 type method struct { 274 name *string // name of method 275 pkgPath *string // nil for exported Names; otherwise import path 276 mtyp *rtype // method type (without receiver) 277 typ *rtype // .(*FuncType) underneath (with receiver) 278 ifn unsafe.Pointer // fn used in interface call (one-word receiver) 279 tfn unsafe.Pointer // fn used for normal method call 280 } 281 282 // uncommonType is present only for types with names or methods 283 // (if T is a named type, the uncommonTypes for T and *T have methods). 284 // Using a pointer to this struct reduces the overall size required 285 // to describe an unnamed type with no methods. 286 type uncommonType struct { 287 name *string // name of type 288 pkgPath *string // import path; nil for built-in types like int, string 289 methods []method // methods associated with type 290 } 291 292 // ChanDir represents a channel type's direction. 293 type ChanDir int 294 295 const ( 296 RecvDir ChanDir = 1 << iota // <-chan 297 SendDir // chan<- 298 BothDir = RecvDir | SendDir // chan 299 ) 300 301 // arrayType represents a fixed array type. 302 type arrayType struct { 303 rtype `reflect:"array"` 304 elem *rtype // array element type 305 slice *rtype // slice type 306 len uintptr 307 } 308 309 // chanType represents a channel type. 310 type chanType struct { 311 rtype `reflect:"chan"` 312 elem *rtype // channel element type 313 dir uintptr // channel direction (ChanDir) 314 } 315 316 // funcType represents a function type. 317 type funcType struct { 318 rtype `reflect:"func"` 319 dotdotdot bool // last input parameter is ... 320 in []*rtype // input parameter types 321 out []*rtype // output parameter types 322 } 323 324 // imethod represents a method on an interface type 325 type imethod struct { 326 name *string // name of method 327 pkgPath *string // nil for exported Names; otherwise import path 328 typ *rtype // .(*FuncType) underneath 329 } 330 331 // interfaceType represents an interface type. 332 type interfaceType struct { 333 rtype `reflect:"interface"` 334 methods []imethod // sorted by hash 335 } 336 337 // mapType represents a map type. 338 type mapType struct { 339 rtype `reflect:"map"` 340 key *rtype // map key type 341 elem *rtype // map element (value) type 342 bucket *rtype // internal bucket structure 343 hmap *rtype // internal map header 344 keysize uint8 // size of key slot 345 indirectkey uint8 // store ptr to key instead of key itself 346 valuesize uint8 // size of value slot 347 indirectvalue uint8 // store ptr to value instead of value itself 348 bucketsize uint16 // size of bucket 349 reflexivekey bool // true if k==k for all keys 350 needkeyupdate bool // true if we need to update key on an overwrite 351 } 352 353 // ptrType represents a pointer type. 354 type ptrType struct { 355 rtype `reflect:"ptr"` 356 elem *rtype // pointer element (pointed at) type 357 } 358 359 // sliceType represents a slice type. 360 type sliceType struct { 361 rtype `reflect:"slice"` 362 elem *rtype // slice element type 363 } 364 365 // Struct field 366 type structField struct { 367 name *string // nil for embedded fields 368 pkgPath *string // nil for exported Names; otherwise import path 369 typ *rtype // type of field 370 tag *string // nil if no tag 371 offset uintptr // byte offset of field within struct 372 } 373 374 // structType represents a struct type. 375 type structType struct { 376 rtype `reflect:"struct"` 377 fields []structField // sorted by offset 378 } 379 380 /* 381 * The compiler knows the exact layout of all the data structures above. 382 * The compiler does not know about the data structures and methods below. 383 */ 384 385 // Method represents a single method. 386 type Method struct { 387 // Name is the method name. 388 // PkgPath is the package path that qualifies a lower case (unexported) 389 // method name. It is empty for upper case (exported) method names. 390 // The combination of PkgPath and Name uniquely identifies a method 391 // in a method set. 392 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 393 Name string 394 PkgPath string 395 396 Type Type // method type 397 Func Value // func with receiver as first argument 398 Index int // index for Type.Method 399 } 400 401 const ( 402 kindDirectIface = 1 << 5 403 kindGCProg = 1 << 6 // Type.gc points to GC program 404 kindNoPointers = 1 << 7 405 kindMask = (1 << 5) - 1 406 ) 407 408 func (k Kind) String() string { 409 if int(k) < len(kindNames) { 410 return kindNames[k] 411 } 412 return "kind" + strconv.Itoa(int(k)) 413 } 414 415 var kindNames = []string{ 416 Invalid: "invalid", 417 Bool: "bool", 418 Int: "int", 419 Int8: "int8", 420 Int16: "int16", 421 Int32: "int32", 422 Int64: "int64", 423 Uint: "uint", 424 Uint8: "uint8", 425 Uint16: "uint16", 426 Uint32: "uint32", 427 Uint64: "uint64", 428 Uintptr: "uintptr", 429 Float32: "float32", 430 Float64: "float64", 431 Complex64: "complex64", 432 Complex128: "complex128", 433 Array: "array", 434 Chan: "chan", 435 Func: "func", 436 Interface: "interface", 437 Map: "map", 438 Ptr: "ptr", 439 Slice: "slice", 440 String: "string", 441 Struct: "struct", 442 UnsafePointer: "unsafe.Pointer", 443 } 444 445 func (t *uncommonType) uncommon() *uncommonType { 446 return t 447 } 448 449 func (t *uncommonType) PkgPath() string { 450 if t == nil || t.pkgPath == nil { 451 return "" 452 } 453 return *t.pkgPath 454 } 455 456 func (t *uncommonType) Name() string { 457 if t == nil || t.name == nil { 458 return "" 459 } 460 return *t.name 461 } 462 463 func (t *rtype) String() string { return *t.string } 464 465 func (t *rtype) Size() uintptr { return t.size } 466 467 func (t *rtype) Bits() int { 468 if t == nil { 469 panic("reflect: Bits of nil Type") 470 } 471 k := t.Kind() 472 if k < Int || k > Complex128 { 473 panic("reflect: Bits of non-arithmetic Type " + t.String()) 474 } 475 return int(t.size) * 8 476 } 477 478 func (t *rtype) Align() int { return int(t.align) } 479 480 func (t *rtype) FieldAlign() int { return int(t.fieldAlign) } 481 482 func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) } 483 484 func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 } 485 486 func (t *rtype) common() *rtype { return t } 487 488 func (t *uncommonType) Method(i int) (m Method) { 489 if t == nil || i < 0 || i >= len(t.methods) { 490 panic("reflect: Method index out of range") 491 } 492 p := &t.methods[i] 493 if p.name != nil { 494 m.Name = *p.name 495 } 496 fl := flag(Func) 497 if p.pkgPath != nil { 498 m.PkgPath = *p.pkgPath 499 fl |= flagStickyRO 500 } 501 mt := p.typ 502 m.Type = mt 503 fn := unsafe.Pointer(&p.tfn) 504 m.Func = Value{mt, fn, fl} 505 m.Index = i 506 return 507 } 508 509 func (t *uncommonType) NumMethod() int { 510 if t == nil { 511 return 0 512 } 513 return len(t.methods) 514 } 515 516 func (t *uncommonType) MethodByName(name string) (m Method, ok bool) { 517 if t == nil { 518 return 519 } 520 var p *method 521 for i := range t.methods { 522 p = &t.methods[i] 523 if p.name != nil && *p.name == name { 524 return t.Method(i), true 525 } 526 } 527 return 528 } 529 530 // TODO(rsc): gc supplies these, but they are not 531 // as efficient as they could be: they have commonType 532 // as the receiver instead of *rtype. 533 func (t *rtype) NumMethod() int { 534 if t.Kind() == Interface { 535 tt := (*interfaceType)(unsafe.Pointer(t)) 536 return tt.NumMethod() 537 } 538 return t.uncommonType.NumMethod() 539 } 540 541 func (t *rtype) Method(i int) (m Method) { 542 if t.Kind() == Interface { 543 tt := (*interfaceType)(unsafe.Pointer(t)) 544 return tt.Method(i) 545 } 546 return t.uncommonType.Method(i) 547 } 548 549 func (t *rtype) MethodByName(name string) (m Method, ok bool) { 550 if t.Kind() == Interface { 551 tt := (*interfaceType)(unsafe.Pointer(t)) 552 return tt.MethodByName(name) 553 } 554 return t.uncommonType.MethodByName(name) 555 } 556 557 func (t *rtype) PkgPath() string { 558 return t.uncommonType.PkgPath() 559 } 560 561 func (t *rtype) Name() string { 562 return t.uncommonType.Name() 563 } 564 565 func (t *rtype) ChanDir() ChanDir { 566 if t.Kind() != Chan { 567 panic("reflect: ChanDir of non-chan type") 568 } 569 tt := (*chanType)(unsafe.Pointer(t)) 570 return ChanDir(tt.dir) 571 } 572 573 func (t *rtype) IsVariadic() bool { 574 if t.Kind() != Func { 575 panic("reflect: IsVariadic of non-func type") 576 } 577 tt := (*funcType)(unsafe.Pointer(t)) 578 return tt.dotdotdot 579 } 580 581 func (t *rtype) Elem() Type { 582 switch t.Kind() { 583 case Array: 584 tt := (*arrayType)(unsafe.Pointer(t)) 585 return toType(tt.elem) 586 case Chan: 587 tt := (*chanType)(unsafe.Pointer(t)) 588 return toType(tt.elem) 589 case Map: 590 tt := (*mapType)(unsafe.Pointer(t)) 591 return toType(tt.elem) 592 case Ptr: 593 tt := (*ptrType)(unsafe.Pointer(t)) 594 return toType(tt.elem) 595 case Slice: 596 tt := (*sliceType)(unsafe.Pointer(t)) 597 return toType(tt.elem) 598 } 599 panic("reflect: Elem of invalid type") 600 } 601 602 func (t *rtype) Field(i int) StructField { 603 if t.Kind() != Struct { 604 panic("reflect: Field of non-struct type") 605 } 606 tt := (*structType)(unsafe.Pointer(t)) 607 return tt.Field(i) 608 } 609 610 func (t *rtype) FieldByIndex(index []int) StructField { 611 if t.Kind() != Struct { 612 panic("reflect: FieldByIndex of non-struct type") 613 } 614 tt := (*structType)(unsafe.Pointer(t)) 615 return tt.FieldByIndex(index) 616 } 617 618 func (t *rtype) FieldByName(name string) (StructField, bool) { 619 if t.Kind() != Struct { 620 panic("reflect: FieldByName of non-struct type") 621 } 622 tt := (*structType)(unsafe.Pointer(t)) 623 return tt.FieldByName(name) 624 } 625 626 func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { 627 if t.Kind() != Struct { 628 panic("reflect: FieldByNameFunc of non-struct type") 629 } 630 tt := (*structType)(unsafe.Pointer(t)) 631 return tt.FieldByNameFunc(match) 632 } 633 634 func (t *rtype) In(i int) Type { 635 if t.Kind() != Func { 636 panic("reflect: In of non-func type") 637 } 638 tt := (*funcType)(unsafe.Pointer(t)) 639 return toType(tt.in[i]) 640 } 641 642 func (t *rtype) Key() Type { 643 if t.Kind() != Map { 644 panic("reflect: Key of non-map type") 645 } 646 tt := (*mapType)(unsafe.Pointer(t)) 647 return toType(tt.key) 648 } 649 650 func (t *rtype) Len() int { 651 if t.Kind() != Array { 652 panic("reflect: Len of non-array type") 653 } 654 tt := (*arrayType)(unsafe.Pointer(t)) 655 return int(tt.len) 656 } 657 658 func (t *rtype) NumField() int { 659 if t.Kind() != Struct { 660 panic("reflect: NumField of non-struct type") 661 } 662 tt := (*structType)(unsafe.Pointer(t)) 663 return len(tt.fields) 664 } 665 666 func (t *rtype) NumIn() int { 667 if t.Kind() != Func { 668 panic("reflect: NumIn of non-func type") 669 } 670 tt := (*funcType)(unsafe.Pointer(t)) 671 return len(tt.in) 672 } 673 674 func (t *rtype) NumOut() int { 675 if t.Kind() != Func { 676 panic("reflect: NumOut of non-func type") 677 } 678 tt := (*funcType)(unsafe.Pointer(t)) 679 return len(tt.out) 680 } 681 682 func (t *rtype) Out(i int) Type { 683 if t.Kind() != Func { 684 panic("reflect: Out of non-func type") 685 } 686 tt := (*funcType)(unsafe.Pointer(t)) 687 return toType(tt.out[i]) 688 } 689 690 func (d ChanDir) String() string { 691 switch d { 692 case SendDir: 693 return "chan<-" 694 case RecvDir: 695 return "<-chan" 696 case BothDir: 697 return "chan" 698 } 699 return "ChanDir" + strconv.Itoa(int(d)) 700 } 701 702 // Method returns the i'th method in the type's method set. 703 func (t *interfaceType) Method(i int) (m Method) { 704 if i < 0 || i >= len(t.methods) { 705 return 706 } 707 p := &t.methods[i] 708 m.Name = *p.name 709 if p.pkgPath != nil { 710 m.PkgPath = *p.pkgPath 711 } 712 m.Type = toType(p.typ) 713 m.Index = i 714 return 715 } 716 717 // NumMethod returns the number of interface methods in the type's method set. 718 func (t *interfaceType) NumMethod() int { return len(t.methods) } 719 720 // MethodByName method with the given name in the type's method set. 721 func (t *interfaceType) MethodByName(name string) (m Method, ok bool) { 722 if t == nil { 723 return 724 } 725 var p *imethod 726 for i := range t.methods { 727 p = &t.methods[i] 728 if *p.name == name { 729 return t.Method(i), true 730 } 731 } 732 return 733 } 734 735 // A StructField describes a single field in a struct. 736 type StructField struct { 737 // Name is the field name. 738 Name string 739 // PkgPath is the package path that qualifies a lower case (unexported) 740 // field name. It is empty for upper case (exported) field names. 741 // See https://golang.org/ref/spec#Uniqueness_of_identifiers 742 PkgPath string 743 744 Type Type // field type 745 Tag StructTag // field tag string 746 Offset uintptr // offset within struct, in bytes 747 Index []int // index sequence for Type.FieldByIndex 748 Anonymous bool // is an embedded field 749 } 750 751 // A StructTag is the tag string in a struct field. 752 // 753 // By convention, tag strings are a concatenation of 754 // optionally space-separated key:"value" pairs. 755 // Each key is a non-empty string consisting of non-control 756 // characters other than space (U+0020 ' '), quote (U+0022 '"'), 757 // and colon (U+003A ':'). Each value is quoted using U+0022 '"' 758 // characters and Go string literal syntax. 759 type StructTag string 760 761 // Get returns the value associated with key in the tag string. 762 // If there is no such key in the tag, Get returns the empty string. 763 // If the tag does not have the conventional format, the value 764 // returned by Get is unspecified. 765 func (tag StructTag) Get(key string) string { 766 // When modifying this code, also update the validateStructTag code 767 // in golang.org/x/tools/cmd/vet/structtag.go. 768 769 for tag != "" { 770 // Skip leading space. 771 i := 0 772 for i < len(tag) && tag[i] == ' ' { 773 i++ 774 } 775 tag = tag[i:] 776 if tag == "" { 777 break 778 } 779 780 // Scan to colon. A space, a quote or a control character is a syntax error. 781 // Strictly speaking, control chars include the range [0x7f, 0x9f], not just 782 // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters 783 // as it is simpler to inspect the tag's bytes than the tag's runes. 784 i = 0 785 for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f { 786 i++ 787 } 788 if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' { 789 break 790 } 791 name := string(tag[:i]) 792 tag = tag[i+1:] 793 794 // Scan quoted string to find value. 795 i = 1 796 for i < len(tag) && tag[i] != '"' { 797 if tag[i] == '\\' { 798 i++ 799 } 800 i++ 801 } 802 if i >= len(tag) { 803 break 804 } 805 qvalue := string(tag[:i+1]) 806 tag = tag[i+1:] 807 808 if key == name { 809 value, err := strconv.Unquote(qvalue) 810 if err != nil { 811 break 812 } 813 return value 814 } 815 } 816 return "" 817 } 818 819 // Field returns the i'th struct field. 820 func (t *structType) Field(i int) (f StructField) { 821 if i < 0 || i >= len(t.fields) { 822 return 823 } 824 p := &t.fields[i] 825 f.Type = toType(p.typ) 826 if p.name != nil { 827 f.Name = *p.name 828 } else { 829 t := f.Type 830 if t.Kind() == Ptr { 831 t = t.Elem() 832 } 833 f.Name = t.Name() 834 f.Anonymous = true 835 } 836 if p.pkgPath != nil { 837 f.PkgPath = *p.pkgPath 838 } 839 if p.tag != nil { 840 f.Tag = StructTag(*p.tag) 841 } 842 f.Offset = p.offset 843 844 // NOTE(rsc): This is the only allocation in the interface 845 // presented by a reflect.Type. It would be nice to avoid, 846 // at least in the common cases, but we need to make sure 847 // that misbehaving clients of reflect cannot affect other 848 // uses of reflect. One possibility is CL 5371098, but we 849 // postponed that ugliness until there is a demonstrated 850 // need for the performance. This is issue 2320. 851 f.Index = []int{i} 852 return 853 } 854 855 // TODO(gri): Should there be an error/bool indicator if the index 856 // is wrong for FieldByIndex? 857 858 // FieldByIndex returns the nested field corresponding to index. 859 func (t *structType) FieldByIndex(index []int) (f StructField) { 860 f.Type = toType(&t.rtype) 861 for i, x := range index { 862 if i > 0 { 863 ft := f.Type 864 if ft.Kind() == Ptr && ft.Elem().Kind() == Struct { 865 ft = ft.Elem() 866 } 867 f.Type = ft 868 } 869 f = f.Type.Field(x) 870 } 871 return 872 } 873 874 // A fieldScan represents an item on the fieldByNameFunc scan work list. 875 type fieldScan struct { 876 typ *structType 877 index []int 878 } 879 880 // FieldByNameFunc returns the struct field with a name that satisfies the 881 // match function and a boolean to indicate if the field was found. 882 func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) { 883 // This uses the same condition that the Go language does: there must be a unique instance 884 // of the match at a given depth level. If there are multiple instances of a match at the 885 // same depth, they annihilate each other and inhibit any possible match at a lower level. 886 // The algorithm is breadth first search, one depth level at a time. 887 888 // The current and next slices are work queues: 889 // current lists the fields to visit on this depth level, 890 // and next lists the fields on the next lower level. 891 current := []fieldScan{} 892 next := []fieldScan{{typ: t}} 893 894 // nextCount records the number of times an embedded type has been 895 // encountered and considered for queueing in the 'next' slice. 896 // We only queue the first one, but we increment the count on each. 897 // If a struct type T can be reached more than once at a given depth level, 898 // then it annihilates itself and need not be considered at all when we 899 // process that next depth level. 900 var nextCount map[*structType]int 901 902 // visited records the structs that have been considered already. 903 // Embedded pointer fields can create cycles in the graph of 904 // reachable embedded types; visited avoids following those cycles. 905 // It also avoids duplicated effort: if we didn't find the field in an 906 // embedded type T at level 2, we won't find it in one at level 4 either. 907 visited := map[*structType]bool{} 908 909 for len(next) > 0 { 910 current, next = next, current[:0] 911 count := nextCount 912 nextCount = nil 913 914 // Process all the fields at this depth, now listed in 'current'. 915 // The loop queues embedded fields found in 'next', for processing during the next 916 // iteration. The multiplicity of the 'current' field counts is recorded 917 // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'. 918 for _, scan := range current { 919 t := scan.typ 920 if visited[t] { 921 // We've looked through this type before, at a higher level. 922 // That higher level would shadow the lower level we're now at, 923 // so this one can't be useful to us. Ignore it. 924 continue 925 } 926 visited[t] = true 927 for i := range t.fields { 928 f := &t.fields[i] 929 // Find name and type for field f. 930 var fname string 931 var ntyp *rtype 932 if f.name != nil { 933 fname = *f.name 934 } else { 935 // Anonymous field of type T or *T. 936 // Name taken from type. 937 ntyp = f.typ 938 if ntyp.Kind() == Ptr { 939 ntyp = ntyp.Elem().common() 940 } 941 fname = ntyp.Name() 942 } 943 944 // Does it match? 945 if match(fname) { 946 // Potential match 947 if count[t] > 1 || ok { 948 // Name appeared multiple times at this level: annihilate. 949 return StructField{}, false 950 } 951 result = t.Field(i) 952 result.Index = nil 953 result.Index = append(result.Index, scan.index...) 954 result.Index = append(result.Index, i) 955 ok = true 956 continue 957 } 958 959 // Queue embedded struct fields for processing with next level, 960 // but only if we haven't seen a match yet at this level and only 961 // if the embedded types haven't already been queued. 962 if ok || ntyp == nil || ntyp.Kind() != Struct { 963 continue 964 } 965 styp := (*structType)(unsafe.Pointer(ntyp)) 966 if nextCount[styp] > 0 { 967 nextCount[styp] = 2 // exact multiple doesn't matter 968 continue 969 } 970 if nextCount == nil { 971 nextCount = map[*structType]int{} 972 } 973 nextCount[styp] = 1 974 if count[t] > 1 { 975 nextCount[styp] = 2 // exact multiple doesn't matter 976 } 977 var index []int 978 index = append(index, scan.index...) 979 index = append(index, i) 980 next = append(next, fieldScan{styp, index}) 981 } 982 } 983 if ok { 984 break 985 } 986 } 987 return 988 } 989 990 // FieldByName returns the struct field with the given name 991 // and a boolean to indicate if the field was found. 992 func (t *structType) FieldByName(name string) (f StructField, present bool) { 993 // Quick check for top-level name, or struct without anonymous fields. 994 hasAnon := false 995 if name != "" { 996 for i := range t.fields { 997 tf := &t.fields[i] 998 if tf.name == nil { 999 hasAnon = true 1000 continue 1001 } 1002 if *tf.name == name { 1003 return t.Field(i), true 1004 } 1005 } 1006 } 1007 if !hasAnon { 1008 return 1009 } 1010 return t.FieldByNameFunc(func(s string) bool { return s == name }) 1011 } 1012 1013 // TypeOf returns the reflection Type that represents the dynamic type of i. 1014 // If i is a nil interface value, TypeOf returns nil. 1015 func TypeOf(i interface{}) Type { 1016 eface := *(*emptyInterface)(unsafe.Pointer(&i)) 1017 return toType(eface.typ) 1018 } 1019 1020 // ptrMap is the cache for PtrTo. 1021 var ptrMap struct { 1022 sync.RWMutex 1023 m map[*rtype]*ptrType 1024 } 1025 1026 // PtrTo returns the pointer type with element t. 1027 // For example, if t represents type Foo, PtrTo(t) represents *Foo. 1028 func PtrTo(t Type) Type { 1029 return t.(*rtype).ptrTo() 1030 } 1031 1032 func (t *rtype) ptrTo() *rtype { 1033 if p := t.ptrToThis; p != nil { 1034 return p 1035 } 1036 1037 // Otherwise, synthesize one. 1038 // This only happens for pointers with no methods. 1039 // We keep the mapping in a map on the side, because 1040 // this operation is rare and a separate map lets us keep 1041 // the type structures in read-only memory. 1042 ptrMap.RLock() 1043 if m := ptrMap.m; m != nil { 1044 if p := m[t]; p != nil { 1045 ptrMap.RUnlock() 1046 return &p.rtype 1047 } 1048 } 1049 ptrMap.RUnlock() 1050 ptrMap.Lock() 1051 if ptrMap.m == nil { 1052 ptrMap.m = make(map[*rtype]*ptrType) 1053 } 1054 p := ptrMap.m[t] 1055 if p != nil { 1056 // some other goroutine won the race and created it 1057 ptrMap.Unlock() 1058 return &p.rtype 1059 } 1060 1061 // Look in known types. 1062 s := "*" + *t.string 1063 for _, tt := range typesByString(s) { 1064 p = (*ptrType)(unsafe.Pointer(tt)) 1065 if p.elem == t { 1066 ptrMap.m[t] = p 1067 ptrMap.Unlock() 1068 return &p.rtype 1069 } 1070 } 1071 1072 // Create a new ptrType starting with the description 1073 // of an *unsafe.Pointer. 1074 p = new(ptrType) 1075 var iptr interface{} = (*unsafe.Pointer)(nil) 1076 prototype := *(**ptrType)(unsafe.Pointer(&iptr)) 1077 *p = *prototype 1078 1079 p.string = &s 1080 1081 // For the type structures linked into the binary, the 1082 // compiler provides a good hash of the string. 1083 // Create a good hash for the new string by using 1084 // the FNV-1 hash's mixing function to combine the 1085 // old hash and the new "*". 1086 p.hash = fnv1(t.hash, '*') 1087 1088 p.uncommonType = nil 1089 p.ptrToThis = nil 1090 p.elem = t 1091 1092 ptrMap.m[t] = p 1093 ptrMap.Unlock() 1094 return &p.rtype 1095 } 1096 1097 // fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function. 1098 func fnv1(x uint32, list ...byte) uint32 { 1099 for _, b := range list { 1100 x = x*16777619 ^ uint32(b) 1101 } 1102 return x 1103 } 1104 1105 func (t *rtype) Implements(u Type) bool { 1106 if u == nil { 1107 panic("reflect: nil type passed to Type.Implements") 1108 } 1109 if u.Kind() != Interface { 1110 panic("reflect: non-interface type passed to Type.Implements") 1111 } 1112 return implements(u.(*rtype), t) 1113 } 1114 1115 func (t *rtype) AssignableTo(u Type) bool { 1116 if u == nil { 1117 panic("reflect: nil type passed to Type.AssignableTo") 1118 } 1119 uu := u.(*rtype) 1120 return directlyAssignable(uu, t) || implements(uu, t) 1121 } 1122 1123 func (t *rtype) ConvertibleTo(u Type) bool { 1124 if u == nil { 1125 panic("reflect: nil type passed to Type.ConvertibleTo") 1126 } 1127 uu := u.(*rtype) 1128 return convertOp(uu, t) != nil 1129 } 1130 1131 func (t *rtype) Comparable() bool { 1132 return t.alg != nil && t.alg.equal != nil 1133 } 1134 1135 // implements reports whether the type V implements the interface type T. 1136 func implements(T, V *rtype) bool { 1137 if T.Kind() != Interface { 1138 return false 1139 } 1140 t := (*interfaceType)(unsafe.Pointer(T)) 1141 if len(t.methods) == 0 { 1142 return true 1143 } 1144 1145 // The same algorithm applies in both cases, but the 1146 // method tables for an interface type and a concrete type 1147 // are different, so the code is duplicated. 1148 // In both cases the algorithm is a linear scan over the two 1149 // lists - T's methods and V's methods - simultaneously. 1150 // Since method tables are stored in a unique sorted order 1151 // (alphabetical, with no duplicate method names), the scan 1152 // through V's methods must hit a match for each of T's 1153 // methods along the way, or else V does not implement T. 1154 // This lets us run the scan in overall linear time instead of 1155 // the quadratic time a naive search would require. 1156 // See also ../runtime/iface.go. 1157 if V.Kind() == Interface { 1158 v := (*interfaceType)(unsafe.Pointer(V)) 1159 i := 0 1160 for j := 0; j < len(v.methods); j++ { 1161 tm := &t.methods[i] 1162 vm := &v.methods[j] 1163 if *vm.name == *tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ { 1164 if i++; i >= len(t.methods) { 1165 return true 1166 } 1167 } 1168 } 1169 return false 1170 } 1171 1172 v := V.uncommon() 1173 if v == nil { 1174 return false 1175 } 1176 i := 0 1177 for j := 0; j < len(v.methods); j++ { 1178 tm := &t.methods[i] 1179 vm := &v.methods[j] 1180 if *vm.name == *tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ { 1181 if i++; i >= len(t.methods) { 1182 return true 1183 } 1184 } 1185 } 1186 return false 1187 } 1188 1189 // directlyAssignable reports whether a value x of type V can be directly 1190 // assigned (using memmove) to a value of type T. 1191 // https://golang.org/doc/go_spec.html#Assignability 1192 // Ignoring the interface rules (implemented elsewhere) 1193 // and the ideal constant rules (no ideal constants at run time). 1194 func directlyAssignable(T, V *rtype) bool { 1195 // x's type V is identical to T? 1196 if T == V { 1197 return true 1198 } 1199 1200 // Otherwise at least one of T and V must be unnamed 1201 // and they must have the same kind. 1202 if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() { 1203 return false 1204 } 1205 1206 // x's type T and V must have identical underlying types. 1207 return haveIdenticalUnderlyingType(T, V) 1208 } 1209 1210 func haveIdenticalUnderlyingType(T, V *rtype) bool { 1211 if T == V { 1212 return true 1213 } 1214 1215 kind := T.Kind() 1216 if kind != V.Kind() { 1217 return false 1218 } 1219 1220 // Non-composite types of equal kind have same underlying type 1221 // (the predefined instance of the type). 1222 if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer { 1223 return true 1224 } 1225 1226 // Composite types. 1227 switch kind { 1228 case Array: 1229 return T.Elem() == V.Elem() && T.Len() == V.Len() 1230 1231 case Chan: 1232 // Special case: 1233 // x is a bidirectional channel value, T is a channel type, 1234 // and x's type V and T have identical element types. 1235 if V.ChanDir() == BothDir && T.Elem() == V.Elem() { 1236 return true 1237 } 1238 1239 // Otherwise continue test for identical underlying type. 1240 return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem() 1241 1242 case Func: 1243 t := (*funcType)(unsafe.Pointer(T)) 1244 v := (*funcType)(unsafe.Pointer(V)) 1245 if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) { 1246 return false 1247 } 1248 for i, typ := range t.in { 1249 if typ != v.in[i] { 1250 return false 1251 } 1252 } 1253 for i, typ := range t.out { 1254 if typ != v.out[i] { 1255 return false 1256 } 1257 } 1258 return true 1259 1260 case Interface: 1261 t := (*interfaceType)(unsafe.Pointer(T)) 1262 v := (*interfaceType)(unsafe.Pointer(V)) 1263 if len(t.methods) == 0 && len(v.methods) == 0 { 1264 return true 1265 } 1266 // Might have the same methods but still 1267 // need a run time conversion. 1268 return false 1269 1270 case Map: 1271 return T.Key() == V.Key() && T.Elem() == V.Elem() 1272 1273 case Ptr, Slice: 1274 return T.Elem() == V.Elem() 1275 1276 case Struct: 1277 t := (*structType)(unsafe.Pointer(T)) 1278 v := (*structType)(unsafe.Pointer(V)) 1279 if len(t.fields) != len(v.fields) { 1280 return false 1281 } 1282 for i := range t.fields { 1283 tf := &t.fields[i] 1284 vf := &v.fields[i] 1285 if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) { 1286 return false 1287 } 1288 if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) { 1289 return false 1290 } 1291 if tf.typ != vf.typ { 1292 return false 1293 } 1294 if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) { 1295 return false 1296 } 1297 if tf.offset != vf.offset { 1298 return false 1299 } 1300 } 1301 return true 1302 } 1303 1304 return false 1305 } 1306 1307 // typelinks is implemented in package runtime. 1308 // It returns a slice of all the 'typelink' information in the binary, 1309 // which is to say a slice of known types, sorted by string. 1310 // Note that strings are not unique identifiers for types: 1311 // there can be more than one with a given string. 1312 // Only types we might want to look up are included: 1313 // channels, maps, slices, and arrays. 1314 func typelinks() [][]*rtype 1315 1316 // typesByString returns the subslice of typelinks() whose elements have 1317 // the given string representation. 1318 // It may be empty (no known types with that string) or may have 1319 // multiple elements (multiple types with that string). 1320 func typesByString(s string) []*rtype { 1321 typs := typelinks() 1322 var ret []*rtype 1323 1324 for _, typ := range typs { 1325 // We are looking for the first index i where the string becomes >= s. 1326 // This is a copy of sort.Search, with f(h) replaced by (*typ[h].string >= s). 1327 i, j := 0, len(typ) 1328 for i < j { 1329 h := i + (j-i)/2 // avoid overflow when computing h 1330 // i ≤ h < j 1331 if !(*typ[h].string >= s) { 1332 i = h + 1 // preserves f(i-1) == false 1333 } else { 1334 j = h // preserves f(j) == true 1335 } 1336 } 1337 // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. 1338 1339 // Having found the first, linear scan forward to find the last. 1340 // We could do a second binary search, but the caller is going 1341 // to do a linear scan anyway. 1342 j = i 1343 for j < len(typ) && *typ[j].string == s { 1344 j++ 1345 } 1346 1347 if j > i { 1348 if ret == nil { 1349 ret = typ[i:j:j] 1350 } else { 1351 ret = append(ret, typ[i:j]...) 1352 } 1353 } 1354 } 1355 return ret 1356 } 1357 1358 // The lookupCache caches ChanOf, MapOf, and SliceOf lookups. 1359 var lookupCache struct { 1360 sync.RWMutex 1361 m map[cacheKey]*rtype 1362 } 1363 1364 // A cacheKey is the key for use in the lookupCache. 1365 // Four values describe any of the types we are looking for: 1366 // type kind, one or two subtypes, and an extra integer. 1367 type cacheKey struct { 1368 kind Kind 1369 t1 *rtype 1370 t2 *rtype 1371 extra uintptr 1372 } 1373 1374 // cacheGet looks for a type under the key k in the lookupCache. 1375 // If it finds one, it returns that type. 1376 // If not, it returns nil with the cache locked. 1377 // The caller is expected to use cachePut to unlock the cache. 1378 func cacheGet(k cacheKey) Type { 1379 lookupCache.RLock() 1380 t := lookupCache.m[k] 1381 lookupCache.RUnlock() 1382 if t != nil { 1383 return t 1384 } 1385 1386 lookupCache.Lock() 1387 t = lookupCache.m[k] 1388 if t != nil { 1389 lookupCache.Unlock() 1390 return t 1391 } 1392 1393 if lookupCache.m == nil { 1394 lookupCache.m = make(map[cacheKey]*rtype) 1395 } 1396 1397 return nil 1398 } 1399 1400 // cachePut stores the given type in the cache, unlocks the cache, 1401 // and returns the type. It is expected that the cache is locked 1402 // because cacheGet returned nil. 1403 func cachePut(k cacheKey, t *rtype) Type { 1404 lookupCache.m[k] = t 1405 lookupCache.Unlock() 1406 return t 1407 } 1408 1409 // The funcLookupCache caches FuncOf lookups. 1410 // FuncOf does not share the common lookupCache since cacheKey is not 1411 // sufficient to represent functions unambiguously. 1412 var funcLookupCache struct { 1413 sync.RWMutex 1414 m map[uint32][]*rtype // keyed by hash calculated in FuncOf 1415 } 1416 1417 // ChanOf returns the channel type with the given direction and element type. 1418 // For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int. 1419 // 1420 // The gc runtime imposes a limit of 64 kB on channel element types. 1421 // If t's size is equal to or exceeds this limit, ChanOf panics. 1422 func ChanOf(dir ChanDir, t Type) Type { 1423 typ := t.(*rtype) 1424 1425 // Look in cache. 1426 ckey := cacheKey{Chan, typ, nil, uintptr(dir)} 1427 if ch := cacheGet(ckey); ch != nil { 1428 return ch 1429 } 1430 1431 // This restriction is imposed by the gc compiler and the runtime. 1432 if typ.size >= 1<<16 { 1433 lookupCache.Unlock() 1434 panic("reflect.ChanOf: element size too large") 1435 } 1436 1437 // Look in known types. 1438 // TODO: Precedence when constructing string. 1439 var s string 1440 switch dir { 1441 default: 1442 lookupCache.Unlock() 1443 panic("reflect.ChanOf: invalid dir") 1444 case SendDir: 1445 s = "chan<- " + *typ.string 1446 case RecvDir: 1447 s = "<-chan " + *typ.string 1448 case BothDir: 1449 s = "chan " + *typ.string 1450 } 1451 for _, tt := range typesByString(s) { 1452 ch := (*chanType)(unsafe.Pointer(tt)) 1453 if ch.elem == typ && ch.dir == uintptr(dir) { 1454 return cachePut(ckey, tt) 1455 } 1456 } 1457 1458 // Make a channel type. 1459 var ichan interface{} = (chan unsafe.Pointer)(nil) 1460 prototype := *(**chanType)(unsafe.Pointer(&ichan)) 1461 ch := new(chanType) 1462 *ch = *prototype 1463 ch.dir = uintptr(dir) 1464 ch.string = &s 1465 ch.hash = fnv1(typ.hash, 'c', byte(dir)) 1466 ch.elem = typ 1467 ch.uncommonType = nil 1468 ch.ptrToThis = nil 1469 1470 return cachePut(ckey, &ch.rtype) 1471 } 1472 1473 func ismapkey(*rtype) bool // implemented in runtime 1474 1475 // MapOf returns the map type with the given key and element types. 1476 // For example, if k represents int and e represents string, 1477 // MapOf(k, e) represents map[int]string. 1478 // 1479 // If the key type is not a valid map key type (that is, if it does 1480 // not implement Go's == operator), MapOf panics. 1481 func MapOf(key, elem Type) Type { 1482 ktyp := key.(*rtype) 1483 etyp := elem.(*rtype) 1484 1485 if !ismapkey(ktyp) { 1486 panic("reflect.MapOf: invalid key type " + ktyp.String()) 1487 } 1488 1489 // Look in cache. 1490 ckey := cacheKey{Map, ktyp, etyp, 0} 1491 if mt := cacheGet(ckey); mt != nil { 1492 return mt 1493 } 1494 1495 // Look in known types. 1496 s := "map[" + *ktyp.string + "]" + *etyp.string 1497 for _, tt := range typesByString(s) { 1498 mt := (*mapType)(unsafe.Pointer(tt)) 1499 if mt.key == ktyp && mt.elem == etyp { 1500 return cachePut(ckey, tt) 1501 } 1502 } 1503 1504 // Make a map type. 1505 var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil) 1506 mt := new(mapType) 1507 *mt = **(**mapType)(unsafe.Pointer(&imap)) 1508 mt.string = &s 1509 mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash)) 1510 mt.key = ktyp 1511 mt.elem = etyp 1512 mt.bucket = bucketOf(ktyp, etyp) 1513 if ktyp.size > maxKeySize { 1514 mt.keysize = uint8(ptrSize) 1515 mt.indirectkey = 1 1516 } else { 1517 mt.keysize = uint8(ktyp.size) 1518 mt.indirectkey = 0 1519 } 1520 if etyp.size > maxValSize { 1521 mt.valuesize = uint8(ptrSize) 1522 mt.indirectvalue = 1 1523 } else { 1524 mt.valuesize = uint8(etyp.size) 1525 mt.indirectvalue = 0 1526 } 1527 mt.bucketsize = uint16(mt.bucket.size) 1528 mt.reflexivekey = isReflexive(ktyp) 1529 mt.needkeyupdate = needKeyUpdate(ktyp) 1530 mt.uncommonType = nil 1531 mt.ptrToThis = nil 1532 1533 return cachePut(ckey, &mt.rtype) 1534 } 1535 1536 // FuncOf returns the function type with the given argument and result types. 1537 // For example if k represents int and e represents string, 1538 // FuncOf([]Type{k}, []Type{e}, false) represents func(int) string. 1539 // 1540 // The variadic argument controls whether the function is variadic. FuncOf 1541 // panics if the in[len(in)-1] does not represent a slice and variadic is 1542 // true. 1543 func FuncOf(in, out []Type, variadic bool) Type { 1544 if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) { 1545 panic("reflect.FuncOf: last arg of variadic func must be slice") 1546 } 1547 1548 // Make a func type. 1549 var ifunc interface{} = (func())(nil) 1550 prototype := *(**funcType)(unsafe.Pointer(&ifunc)) 1551 ft := new(funcType) 1552 *ft = *prototype 1553 1554 // Build a hash and minimally populate ft. 1555 var hash uint32 1556 var fin, fout []*rtype 1557 for _, in := range in { 1558 t := in.(*rtype) 1559 fin = append(fin, t) 1560 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 1561 } 1562 if variadic { 1563 hash = fnv1(hash, 'v') 1564 } 1565 hash = fnv1(hash, '.') 1566 for _, out := range out { 1567 t := out.(*rtype) 1568 fout = append(fout, t) 1569 hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash)) 1570 } 1571 ft.hash = hash 1572 ft.in = fin 1573 ft.out = fout 1574 ft.dotdotdot = variadic 1575 1576 // Look in cache. 1577 funcLookupCache.RLock() 1578 for _, t := range funcLookupCache.m[hash] { 1579 if haveIdenticalUnderlyingType(&ft.rtype, t) { 1580 funcLookupCache.RUnlock() 1581 return t 1582 } 1583 } 1584 funcLookupCache.RUnlock() 1585 1586 // Not in cache, lock and retry. 1587 funcLookupCache.Lock() 1588 defer funcLookupCache.Unlock() 1589 if funcLookupCache.m == nil { 1590 funcLookupCache.m = make(map[uint32][]*rtype) 1591 } 1592 for _, t := range funcLookupCache.m[hash] { 1593 if haveIdenticalUnderlyingType(&ft.rtype, t) { 1594 return t 1595 } 1596 } 1597 1598 // Look in known types for the same string representation. 1599 str := funcStr(ft) 1600 for _, tt := range typesByString(str) { 1601 if haveIdenticalUnderlyingType(&ft.rtype, tt) { 1602 funcLookupCache.m[hash] = append(funcLookupCache.m[hash], tt) 1603 return tt 1604 } 1605 } 1606 1607 // Populate the remaining fields of ft and store in cache. 1608 ft.string = &str 1609 ft.uncommonType = nil 1610 ft.ptrToThis = nil 1611 funcLookupCache.m[hash] = append(funcLookupCache.m[hash], &ft.rtype) 1612 1613 return &ft.rtype 1614 } 1615 1616 // funcStr builds a string representation of a funcType. 1617 func funcStr(ft *funcType) string { 1618 repr := make([]byte, 0, 64) 1619 repr = append(repr, "func("...) 1620 for i, t := range ft.in { 1621 if i > 0 { 1622 repr = append(repr, ", "...) 1623 } 1624 if ft.dotdotdot && i == len(ft.in)-1 { 1625 repr = append(repr, "..."...) 1626 repr = append(repr, *(*sliceType)(unsafe.Pointer(t)).elem.string...) 1627 } else { 1628 repr = append(repr, *t.string...) 1629 } 1630 } 1631 repr = append(repr, ')') 1632 if l := len(ft.out); l == 1 { 1633 repr = append(repr, ' ') 1634 } else if l > 1 { 1635 repr = append(repr, " ("...) 1636 } 1637 for i, t := range ft.out { 1638 if i > 0 { 1639 repr = append(repr, ", "...) 1640 } 1641 repr = append(repr, *t.string...) 1642 } 1643 if len(ft.out) > 1 { 1644 repr = append(repr, ')') 1645 } 1646 return string(repr) 1647 } 1648 1649 // isReflexive reports whether the == operation on the type is reflexive. 1650 // That is, x == x for all values x of type t. 1651 func isReflexive(t *rtype) bool { 1652 switch t.Kind() { 1653 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, String, UnsafePointer: 1654 return true 1655 case Float32, Float64, Complex64, Complex128, Interface: 1656 return false 1657 case Array: 1658 tt := (*arrayType)(unsafe.Pointer(t)) 1659 return isReflexive(tt.elem) 1660 case Struct: 1661 tt := (*structType)(unsafe.Pointer(t)) 1662 for _, f := range tt.fields { 1663 if !isReflexive(f.typ) { 1664 return false 1665 } 1666 } 1667 return true 1668 default: 1669 // Func, Map, Slice, Invalid 1670 panic("isReflexive called on non-key type " + t.String()) 1671 } 1672 } 1673 1674 // needKeyUpdate reports whether map overwrites require the key to be copied. 1675 func needKeyUpdate(t *rtype) bool { 1676 switch t.Kind() { 1677 case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Ptr, UnsafePointer: 1678 return false 1679 case Float32, Float64, Complex64, Complex128, Interface, String: 1680 // Float keys can be updated from +0 to -0. 1681 // String keys can be updated to use a smaller backing store. 1682 // Interfaces might have floats of strings in them. 1683 return true 1684 case Array: 1685 tt := (*arrayType)(unsafe.Pointer(t)) 1686 return needKeyUpdate(tt.elem) 1687 case Struct: 1688 tt := (*structType)(unsafe.Pointer(t)) 1689 for _, f := range tt.fields { 1690 if needKeyUpdate(f.typ) { 1691 return true 1692 } 1693 } 1694 return false 1695 default: 1696 // Func, Map, Slice, Invalid 1697 panic("needKeyUpdate called on non-key type " + t.String()) 1698 } 1699 } 1700 1701 // Make sure these routines stay in sync with ../../runtime/hashmap.go! 1702 // These types exist only for GC, so we only fill out GC relevant info. 1703 // Currently, that's just size and the GC program. We also fill in string 1704 // for possible debugging use. 1705 const ( 1706 bucketSize uintptr = 8 1707 maxKeySize uintptr = 128 1708 maxValSize uintptr = 128 1709 ) 1710 1711 func bucketOf(ktyp, etyp *rtype) *rtype { 1712 // See comment on hmap.overflow in ../runtime/hashmap.go. 1713 var kind uint8 1714 if ktyp.kind&kindNoPointers != 0 && etyp.kind&kindNoPointers != 0 && 1715 ktyp.size <= maxKeySize && etyp.size <= maxValSize { 1716 kind = kindNoPointers 1717 } 1718 1719 if ktyp.size > maxKeySize { 1720 ktyp = PtrTo(ktyp).(*rtype) 1721 } 1722 if etyp.size > maxValSize { 1723 etyp = PtrTo(etyp).(*rtype) 1724 } 1725 1726 // Prepare GC data if any. 1727 // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+2*ptrSize bytes, 1728 // or 2072 bytes, or 259 pointer-size words, or 33 bytes of pointer bitmap. 1729 // Normally the enforced limit on pointer maps is 16 bytes, 1730 // but larger ones are acceptable, 33 bytes isn't too too big, 1731 // and it's easier to generate a pointer bitmap than a GC program. 1732 // Note that since the key and value are known to be <= 128 bytes, 1733 // they're guaranteed to have bitmaps instead of GC programs. 1734 var gcdata *byte 1735 var ptrdata uintptr 1736 var overflowPad uintptr 1737 1738 // On NaCl, pad if needed to make overflow end at the proper struct alignment. 1739 // On other systems, align > ptrSize is not possible. 1740 if runtime.GOARCH == "amd64p32" && (ktyp.align > ptrSize || etyp.align > ptrSize) { 1741 overflowPad = ptrSize 1742 } 1743 size := bucketSize*(1+ktyp.size+etyp.size) + overflowPad + ptrSize 1744 if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 { 1745 panic("reflect: bad size computation in MapOf") 1746 } 1747 1748 if kind != kindNoPointers { 1749 nptr := (bucketSize*(1+ktyp.size+etyp.size) + ptrSize) / ptrSize 1750 mask := make([]byte, (nptr+7)/8) 1751 base := bucketSize / ptrSize 1752 1753 if ktyp.kind&kindNoPointers == 0 { 1754 if ktyp.kind&kindGCProg != 0 { 1755 panic("reflect: unexpected GC program in MapOf") 1756 } 1757 kmask := (*[16]byte)(unsafe.Pointer(ktyp.gcdata)) 1758 for i := uintptr(0); i < ktyp.size/ptrSize; i++ { 1759 if (kmask[i/8]>>(i%8))&1 != 0 { 1760 for j := uintptr(0); j < bucketSize; j++ { 1761 word := base + j*ktyp.size/ptrSize + i 1762 mask[word/8] |= 1 << (word % 8) 1763 } 1764 } 1765 } 1766 } 1767 base += bucketSize * ktyp.size / ptrSize 1768 1769 if etyp.kind&kindNoPointers == 0 { 1770 if etyp.kind&kindGCProg != 0 { 1771 panic("reflect: unexpected GC program in MapOf") 1772 } 1773 emask := (*[16]byte)(unsafe.Pointer(etyp.gcdata)) 1774 for i := uintptr(0); i < etyp.size/ptrSize; i++ { 1775 if (emask[i/8]>>(i%8))&1 != 0 { 1776 for j := uintptr(0); j < bucketSize; j++ { 1777 word := base + j*etyp.size/ptrSize + i 1778 mask[word/8] |= 1 << (word % 8) 1779 } 1780 } 1781 } 1782 } 1783 base += bucketSize * etyp.size / ptrSize 1784 base += overflowPad / ptrSize 1785 1786 word := base 1787 mask[word/8] |= 1 << (word % 8) 1788 gcdata = &mask[0] 1789 ptrdata = (word + 1) * ptrSize 1790 1791 // overflow word must be last 1792 if ptrdata != size { 1793 panic("reflect: bad layout computation in MapOf") 1794 } 1795 } 1796 1797 b := new(rtype) 1798 b.align = ptrSize 1799 if overflowPad > 0 { 1800 b.align = 8 1801 } 1802 b.size = size 1803 b.ptrdata = ptrdata 1804 b.kind = kind 1805 b.gcdata = gcdata 1806 s := "bucket(" + *ktyp.string + "," + *etyp.string + ")" 1807 b.string = &s 1808 return b 1809 } 1810 1811 // SliceOf returns the slice type with element type t. 1812 // For example, if t represents int, SliceOf(t) represents []int. 1813 func SliceOf(t Type) Type { 1814 typ := t.(*rtype) 1815 1816 // Look in cache. 1817 ckey := cacheKey{Slice, typ, nil, 0} 1818 if slice := cacheGet(ckey); slice != nil { 1819 return slice 1820 } 1821 1822 // Look in known types. 1823 s := "[]" + *typ.string 1824 for _, tt := range typesByString(s) { 1825 slice := (*sliceType)(unsafe.Pointer(tt)) 1826 if slice.elem == typ { 1827 return cachePut(ckey, tt) 1828 } 1829 } 1830 1831 // Make a slice type. 1832 var islice interface{} = ([]unsafe.Pointer)(nil) 1833 prototype := *(**sliceType)(unsafe.Pointer(&islice)) 1834 slice := new(sliceType) 1835 *slice = *prototype 1836 slice.string = &s 1837 slice.hash = fnv1(typ.hash, '[') 1838 slice.elem = typ 1839 slice.uncommonType = nil 1840 slice.ptrToThis = nil 1841 1842 return cachePut(ckey, &slice.rtype) 1843 } 1844 1845 // See cmd/compile/internal/gc/reflect.go for derivation of constant. 1846 const maxPtrmaskBytes = 2048 1847 1848 // ArrayOf returns the array type with the given count and element type. 1849 // For example, if t represents int, ArrayOf(5, t) represents [5]int. 1850 // 1851 // If the resulting type would be larger than the available address space, 1852 // ArrayOf panics. 1853 func ArrayOf(count int, elem Type) Type { 1854 typ := elem.(*rtype) 1855 // call SliceOf here as it calls cacheGet/cachePut. 1856 // ArrayOf also calls cacheGet/cachePut and thus may modify the state of 1857 // the lookupCache mutex. 1858 slice := SliceOf(elem) 1859 1860 // Look in cache. 1861 ckey := cacheKey{Array, typ, nil, uintptr(count)} 1862 if array := cacheGet(ckey); array != nil { 1863 return array 1864 } 1865 1866 // Look in known types. 1867 s := "[" + strconv.Itoa(count) + "]" + *typ.string 1868 for _, tt := range typesByString(s) { 1869 array := (*arrayType)(unsafe.Pointer(tt)) 1870 if array.elem == typ { 1871 return cachePut(ckey, tt) 1872 } 1873 } 1874 1875 // Make an array type. 1876 var iarray interface{} = [1]unsafe.Pointer{} 1877 prototype := *(**arrayType)(unsafe.Pointer(&iarray)) 1878 array := new(arrayType) 1879 *array = *prototype 1880 array.string = &s 1881 array.hash = fnv1(typ.hash, '[') 1882 for n := uint32(count); n > 0; n >>= 8 { 1883 array.hash = fnv1(array.hash, byte(n)) 1884 } 1885 array.hash = fnv1(array.hash, ']') 1886 array.elem = typ 1887 max := ^uintptr(0) / typ.size 1888 if uintptr(count) > max { 1889 panic("reflect.ArrayOf: array size would exceed virtual address space") 1890 } 1891 array.size = typ.size * uintptr(count) 1892 if count > 0 && typ.ptrdata != 0 { 1893 array.ptrdata = typ.size*uintptr(count-1) + typ.ptrdata 1894 } 1895 array.align = typ.align 1896 array.fieldAlign = typ.fieldAlign 1897 array.uncommonType = nil 1898 array.ptrToThis = nil 1899 array.len = uintptr(count) 1900 array.slice = slice.(*rtype) 1901 1902 array.kind &^= kindNoPointers 1903 switch { 1904 case typ.kind&kindNoPointers != 0 || array.size == 0: 1905 // No pointers. 1906 array.kind |= kindNoPointers 1907 array.gcdata = nil 1908 array.ptrdata = 0 1909 1910 case count == 1: 1911 // In memory, 1-element array looks just like the element. 1912 array.kind |= typ.kind & kindGCProg 1913 array.gcdata = typ.gcdata 1914 array.ptrdata = typ.ptrdata 1915 1916 case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*ptrSize: 1917 // Element is small with pointer mask; array is still small. 1918 // Create direct pointer mask by turning each 1 bit in elem 1919 // into count 1 bits in larger mask. 1920 mask := make([]byte, (array.ptrdata/ptrSize+7)/8) 1921 elemMask := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] 1922 elemWords := typ.size / ptrSize 1923 for j := uintptr(0); j < typ.ptrdata/ptrSize; j++ { 1924 if (elemMask[j/8]>>(j%8))&1 != 0 { 1925 for i := uintptr(0); i < array.len; i++ { 1926 k := i*elemWords + j 1927 mask[k/8] |= 1 << (k % 8) 1928 } 1929 } 1930 } 1931 array.gcdata = &mask[0] 1932 1933 default: 1934 // Create program that emits one element 1935 // and then repeats to make the array. 1936 prog := []byte{0, 0, 0, 0} // will be length of prog 1937 elemGC := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] 1938 elemPtrs := typ.ptrdata / ptrSize 1939 if typ.kind&kindGCProg == 0 { 1940 // Element is small with pointer mask; use as literal bits. 1941 mask := elemGC 1942 // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). 1943 var n uintptr 1944 for n = elemPtrs; n > 120; n -= 120 { 1945 prog = append(prog, 120) 1946 prog = append(prog, mask[:15]...) 1947 mask = mask[15:] 1948 } 1949 prog = append(prog, byte(n)) 1950 prog = append(prog, mask[:(n+7)/8]...) 1951 } else { 1952 // Element has GC program; emit one element. 1953 elemProg := elemGC[4 : 4+*(*uint32)(unsafe.Pointer(&elemGC[0]))-1] 1954 prog = append(prog, elemProg...) 1955 } 1956 // Pad from ptrdata to size. 1957 elemWords := typ.size / ptrSize 1958 if elemPtrs < elemWords { 1959 // Emit literal 0 bit, then repeat as needed. 1960 prog = append(prog, 0x01, 0x00) 1961 if elemPtrs+1 < elemWords { 1962 prog = append(prog, 0x81) 1963 prog = appendVarint(prog, elemWords-elemPtrs-1) 1964 } 1965 } 1966 // Repeat count-1 times. 1967 if elemWords < 0x80 { 1968 prog = append(prog, byte(elemWords|0x80)) 1969 } else { 1970 prog = append(prog, 0x80) 1971 prog = appendVarint(prog, elemWords) 1972 } 1973 prog = appendVarint(prog, uintptr(count)-1) 1974 prog = append(prog, 0) 1975 *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4) 1976 array.kind |= kindGCProg 1977 array.gcdata = &prog[0] 1978 array.ptrdata = array.size // overestimate but ok; must match program 1979 } 1980 1981 etyp := typ.common() 1982 esize := etyp.Size() 1983 ealg := etyp.alg 1984 1985 array.alg = new(typeAlg) 1986 if ealg.equal != nil { 1987 eequal := ealg.equal 1988 array.alg.equal = func(p, q unsafe.Pointer) bool { 1989 for i := 0; i < count; i++ { 1990 pi := arrayAt(p, i, esize) 1991 qi := arrayAt(q, i, esize) 1992 if !eequal(pi, qi) { 1993 return false 1994 } 1995 1996 } 1997 return true 1998 } 1999 } 2000 if ealg.hash != nil { 2001 ehash := ealg.hash 2002 array.alg.hash = func(ptr unsafe.Pointer, seed uintptr) uintptr { 2003 o := seed 2004 for i := 0; i < count; i++ { 2005 o = ehash(arrayAt(ptr, i, esize), o) 2006 } 2007 return o 2008 } 2009 } 2010 2011 switch { 2012 case count == 1 && !ifaceIndir(typ): 2013 // array of 1 direct iface type can be direct 2014 array.kind |= kindDirectIface 2015 default: 2016 array.kind &^= kindDirectIface 2017 } 2018 2019 return cachePut(ckey, &array.rtype) 2020 } 2021 2022 func appendVarint(x []byte, v uintptr) []byte { 2023 for ; v >= 0x80; v >>= 7 { 2024 x = append(x, byte(v|0x80)) 2025 } 2026 x = append(x, byte(v)) 2027 return x 2028 } 2029 2030 // toType converts from a *rtype to a Type that can be returned 2031 // to the client of package reflect. In gc, the only concern is that 2032 // a nil *rtype must be replaced by a nil Type, but in gccgo this 2033 // function takes care of ensuring that multiple *rtype for the same 2034 // type are coalesced into a single Type. 2035 func toType(t *rtype) Type { 2036 if t == nil { 2037 return nil 2038 } 2039 return t 2040 } 2041 2042 type layoutKey struct { 2043 t *rtype // function signature 2044 rcvr *rtype // receiver type, or nil if none 2045 } 2046 2047 type layoutType struct { 2048 t *rtype 2049 argSize uintptr // size of arguments 2050 retOffset uintptr // offset of return values. 2051 stack *bitVector 2052 framePool *sync.Pool 2053 } 2054 2055 var layoutCache struct { 2056 sync.RWMutex 2057 m map[layoutKey]layoutType 2058 } 2059 2060 // funcLayout computes a struct type representing the layout of the 2061 // function arguments and return values for the function type t. 2062 // If rcvr != nil, rcvr specifies the type of the receiver. 2063 // The returned type exists only for GC, so we only fill out GC relevant info. 2064 // Currently, that's just size and the GC program. We also fill in 2065 // the name for possible debugging use. 2066 func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stk *bitVector, framePool *sync.Pool) { 2067 if t.Kind() != Func { 2068 panic("reflect: funcLayout of non-func type") 2069 } 2070 if rcvr != nil && rcvr.Kind() == Interface { 2071 panic("reflect: funcLayout with interface receiver " + rcvr.String()) 2072 } 2073 k := layoutKey{t, rcvr} 2074 layoutCache.RLock() 2075 if x := layoutCache.m[k]; x.t != nil { 2076 layoutCache.RUnlock() 2077 return x.t, x.argSize, x.retOffset, x.stack, x.framePool 2078 } 2079 layoutCache.RUnlock() 2080 layoutCache.Lock() 2081 if x := layoutCache.m[k]; x.t != nil { 2082 layoutCache.Unlock() 2083 return x.t, x.argSize, x.retOffset, x.stack, x.framePool 2084 } 2085 2086 tt := (*funcType)(unsafe.Pointer(t)) 2087 2088 // compute gc program & stack bitmap for arguments 2089 ptrmap := new(bitVector) 2090 var offset uintptr 2091 if rcvr != nil { 2092 // Reflect uses the "interface" calling convention for 2093 // methods, where receivers take one word of argument 2094 // space no matter how big they actually are. 2095 if ifaceIndir(rcvr) || rcvr.pointers() { 2096 ptrmap.append(1) 2097 } 2098 offset += ptrSize 2099 } 2100 for _, arg := range tt.in { 2101 offset += -offset & uintptr(arg.align-1) 2102 addTypeBits(ptrmap, offset, arg) 2103 offset += arg.size 2104 } 2105 argN := ptrmap.n 2106 argSize = offset 2107 if runtime.GOARCH == "amd64p32" { 2108 offset += -offset & (8 - 1) 2109 } 2110 offset += -offset & (ptrSize - 1) 2111 retOffset = offset 2112 for _, res := range tt.out { 2113 offset += -offset & uintptr(res.align-1) 2114 addTypeBits(ptrmap, offset, res) 2115 offset += res.size 2116 } 2117 offset += -offset & (ptrSize - 1) 2118 2119 // build dummy rtype holding gc program 2120 x := new(rtype) 2121 x.align = ptrSize 2122 if runtime.GOARCH == "amd64p32" { 2123 x.align = 8 2124 } 2125 x.size = offset 2126 x.ptrdata = uintptr(ptrmap.n) * ptrSize 2127 if ptrmap.n > 0 { 2128 x.gcdata = &ptrmap.data[0] 2129 } else { 2130 x.kind |= kindNoPointers 2131 } 2132 ptrmap.n = argN 2133 2134 var s string 2135 if rcvr != nil { 2136 s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")" 2137 } else { 2138 s = "funcargs(" + *t.string + ")" 2139 } 2140 x.string = &s 2141 2142 // cache result for future callers 2143 if layoutCache.m == nil { 2144 layoutCache.m = make(map[layoutKey]layoutType) 2145 } 2146 framePool = &sync.Pool{New: func() interface{} { 2147 return unsafe_New(x) 2148 }} 2149 layoutCache.m[k] = layoutType{ 2150 t: x, 2151 argSize: argSize, 2152 retOffset: retOffset, 2153 stack: ptrmap, 2154 framePool: framePool, 2155 } 2156 layoutCache.Unlock() 2157 return x, argSize, retOffset, ptrmap, framePool 2158 } 2159 2160 // ifaceIndir reports whether t is stored indirectly in an interface value. 2161 func ifaceIndir(t *rtype) bool { 2162 return t.kind&kindDirectIface == 0 2163 } 2164 2165 // Layout matches runtime.BitVector (well enough). 2166 type bitVector struct { 2167 n uint32 // number of bits 2168 data []byte 2169 } 2170 2171 // append a bit to the bitmap. 2172 func (bv *bitVector) append(bit uint8) { 2173 if bv.n%8 == 0 { 2174 bv.data = append(bv.data, 0) 2175 } 2176 bv.data[bv.n/8] |= bit << (bv.n % 8) 2177 bv.n++ 2178 } 2179 2180 func addTypeBits(bv *bitVector, offset uintptr, t *rtype) { 2181 if t.kind&kindNoPointers != 0 { 2182 return 2183 } 2184 2185 switch Kind(t.kind & kindMask) { 2186 case Chan, Func, Map, Ptr, Slice, String, UnsafePointer: 2187 // 1 pointer at start of representation 2188 for bv.n < uint32(offset/uintptr(ptrSize)) { 2189 bv.append(0) 2190 } 2191 bv.append(1) 2192 2193 case Interface: 2194 // 2 pointers 2195 for bv.n < uint32(offset/uintptr(ptrSize)) { 2196 bv.append(0) 2197 } 2198 bv.append(1) 2199 bv.append(1) 2200 2201 case Array: 2202 // repeat inner type 2203 tt := (*arrayType)(unsafe.Pointer(t)) 2204 for i := 0; i < int(tt.len); i++ { 2205 addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem) 2206 } 2207 2208 case Struct: 2209 // apply fields 2210 tt := (*structType)(unsafe.Pointer(t)) 2211 for i := range tt.fields { 2212 f := &tt.fields[i] 2213 addTypeBits(bv, offset+f.offset, f.typ) 2214 } 2215 } 2216 }