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