...

Source file src/reflect/type.go

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

View as plain text