// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package reflect

import (
	"math"
	"runtime"
	"strconv"
	"unsafe"
)

const ptrSize = uintptr(unsafe.Sizeof((*byte)(nil)))
const cannotSet = "cannot set value obtained from unexported struct field"

// TODO: This will have to go away when
// the new gc goes in.
func memmove(adst, asrc unsafe.Pointer, n uintptr) {
	dst := uintptr(adst)
	src := uintptr(asrc)
	switch {
	case src < dst && src+n > dst:
		// byte copy backward
		// careful: i is unsigned
		for i := n; i > 0; {
			i--
			*(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
		}
	case (n|src|dst)&(ptrSize-1) != 0:
		// byte copy forward
		for i := uintptr(0); i < n; i++ {
			*(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
		}
	default:
		// word copy forward
		for i := uintptr(0); i < n; i += ptrSize {
			*(*uintptr)(unsafe.Pointer(dst + i)) = *(*uintptr)(unsafe.Pointer(src + i))
		}
	}
}

// Value is the reflection interface to a Go value.
//
// Not all methods apply to all kinds of values.  Restrictions,
// if any, are noted in the documentation for each method.
// Use the Kind method to find out the kind of value before
// calling kind-specific methods.  Calling a method
// inappropriate to the kind of type causes a run time panic.
//
// The zero Value represents no value.
// Its IsValid method returns false, its Kind method returns Invalid,
// its String method returns "<invalid Value>", and all other methods panic.
// Most functions and methods never return an invalid value.
// If one does, its documentation states the conditions explicitly.
//
// The fields of Value are exported so that clients can copy and
// pass Values around, but they should not be edited or inspected
// directly.  A future language change may make it possible not to
// export these fields while still keeping Values usable as values.
type Value struct {
	Internal       interface{}
	InternalMethod int
}

// A ValueError occurs when a Value method is invoked on
// a Value that does not support it.  Such cases are documented
// in the description of each method.
type ValueError struct {
	Method string
	Kind   Kind
}

func (e *ValueError) String() string {
	if e.Kind == 0 {
		return "reflect: call of " + e.Method + " on zero Value"
	}
	return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
}

// methodName returns the name of the calling method,
// assumed to be two stack frames above.
func methodName() string {
	pc, _, _, _ := runtime.Caller(2)
	f := runtime.FuncForPC(pc)
	if f == nil {
		return "unknown method"
	}
	return f.Name()
}

// An iword is the word that would be stored in an
// interface to represent a given value v.  Specifically, if v is
// bigger than a pointer, its word is a pointer to v's data.
// Otherwise, its word is a zero uintptr with the data stored
// in the leading bytes.
type iword uintptr

func loadIword(p unsafe.Pointer, size uintptr) iword {
	// Run the copy ourselves instead of calling memmove
	// to avoid moving v to the heap.
	w := iword(0)
	switch size {
	default:
		panic("reflect: internal error: loadIword of " + strconv.Itoa(int(size)) + "-byte value")
	case 0:
	case 1:
		*(*uint8)(unsafe.Pointer(&w)) = *(*uint8)(p)
	case 2:
		*(*uint16)(unsafe.Pointer(&w)) = *(*uint16)(p)
	case 3:
		*(*[3]byte)(unsafe.Pointer(&w)) = *(*[3]byte)(p)
	case 4:
		*(*uint32)(unsafe.Pointer(&w)) = *(*uint32)(p)
	case 5:
		*(*[5]byte)(unsafe.Pointer(&w)) = *(*[5]byte)(p)
	case 6:
		*(*[6]byte)(unsafe.Pointer(&w)) = *(*[6]byte)(p)
	case 7:
		*(*[7]byte)(unsafe.Pointer(&w)) = *(*[7]byte)(p)
	case 8:
		*(*uint64)(unsafe.Pointer(&w)) = *(*uint64)(p)
	}
	return w
}

func storeIword(p unsafe.Pointer, w iword, size uintptr) {
	// Run the copy ourselves instead of calling memmove
	// to avoid moving v to the heap.
	switch size {
	default:
		panic("reflect: internal error: storeIword of " + strconv.Itoa(int(size)) + "-byte value")
	case 0:
	case 1:
		*(*uint8)(p) = *(*uint8)(unsafe.Pointer(&w))
	case 2:
		*(*uint16)(p) = *(*uint16)(unsafe.Pointer(&w))
	case 3:
		*(*[3]byte)(p) = *(*[3]byte)(unsafe.Pointer(&w))
	case 4:
		*(*uint32)(p) = *(*uint32)(unsafe.Pointer(&w))
	case 5:
		*(*[5]byte)(p) = *(*[5]byte)(unsafe.Pointer(&w))
	case 6:
		*(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w))
	case 7:
		*(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w))
	case 8:
		*(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w))
	}
}

// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
	typ  *runtime.Type
	word iword
}

// nonEmptyInterface is the header for a interface value with methods.
type nonEmptyInterface struct {
	// see ../runtime/iface.c:/Itab
	itab *struct {
		ityp   *runtime.Type // static interface type
		typ    *runtime.Type // dynamic concrete type
		link   unsafe.Pointer
		bad    int32
		unused int32
		fun    [100000]unsafe.Pointer // method table
	}
	word iword
}

// Regarding the implementation of Value:
//
// The Internal interface is a true interface value in the Go sense,
// but it also serves as a (type, address) pair in which one cannot
// be changed separately from the other.  That is, it serves as a way
// to prevent unsafe mutations of the Internal state even though
// we cannot (yet?) hide the field while preserving the ability for
// clients to make copies of Values.
//
// The internal method converts a Value into the expanded internalValue struct.
// If we could avoid exporting fields we'd probably make internalValue the
// definition of Value.
//
// If a Value is addressable (CanAddr returns true), then the Internal
// interface value holds a pointer to the actual field data, and Set stores
// through that pointer.  If a Value is not addressable (CanAddr returns false),
// then the Internal interface value holds the actual value.
//
// In addition to whether a value is addressable, we track whether it was
// obtained by using an unexported struct field.  Such values are allowed
// to be read, mainly to make fmt.Print more useful, but they are not
// allowed to be written.  We call such values read-only.
//
// A Value can be set (via the Set, SetUint, etc. methods) only if it is both
// addressable and not read-only.
//
// The two permission bits - addressable and read-only - are stored in
// the bottom two bits of the type pointer in the interface value.
//
//	ordinary value: Internal = value
//	addressable value: Internal = value, Internal.typ |= flagAddr
//	read-only value: Internal = value, Internal.typ |= flagRO
//	addressable, read-only value: Internal = value, Internal.typ |= flagAddr | flagRO
//
// It is important that the read-only values have the extra bit set
// (as opposed to using the bit to mean writable), because client code
// can grab the interface field and try to use it.  Having the extra bit
// set makes the type pointer compare not equal to any real type,
// so that a client cannot, say, write through v.Internal.(*int).
// The runtime routines that access interface types reject types with
// low bits set.
//
// If a Value fv = v.Method(i), then fv = v with the InternalMethod
// field set to i+1.  Methods are never addressable.
//
// All in all, this is a lot of effort just to avoid making this new API
// depend on a language change we'll probably do anyway, but
// it's helpful to keep the two separate, and much of the logic is
// necessary to implement the Interface method anyway.

const (
	flagAddr uint32 = 1 << iota // holds address of value
	flagRO                      // read-only

	reflectFlags = 3
)

// An internalValue is the unpacked form of a Value.
// The zero Value unpacks to a zero internalValue
type internalValue struct {
	typ       *commonType // type of value
	kind      Kind        // kind of value
	flag      uint32
	word      iword
	addr      unsafe.Pointer
	rcvr      iword
	method    bool
	nilmethod bool
}

func (v Value) internal() internalValue {
	var iv internalValue
	eface := *(*emptyInterface)(unsafe.Pointer(&v.Internal))
	p := uintptr(unsafe.Pointer(eface.typ))
	iv.typ = toCommonType((*runtime.Type)(unsafe.Pointer(p &^ reflectFlags)))
	if iv.typ == nil {
		return iv
	}
	iv.flag = uint32(p & reflectFlags)
	iv.word = eface.word
	if iv.flag&flagAddr != 0 {
		iv.addr = unsafe.Pointer(iv.word)
		iv.typ = iv.typ.Elem().common()
		if iv.typ.size <= ptrSize {
			iv.word = loadIword(iv.addr, iv.typ.size)
		}
	} else {
		if iv.typ.size > ptrSize {
			iv.addr = unsafe.Pointer(iv.word)
		}
	}
	iv.kind = iv.typ.Kind()

	// Is this a method?  If so, iv describes the receiver.
	// Rewrite to describe the method function.
	if v.InternalMethod != 0 {
		// If this Value is a method value (x.Method(i) for some Value x)
		// then we will invoke it using the interface form of the method,
		// which always passes the receiver as a single word.
		// Record that information.
		i := v.InternalMethod - 1
		if iv.kind == Interface {
			it := (*interfaceType)(unsafe.Pointer(iv.typ))
			if i < 0 || i >= len(it.methods) {
				panic("reflect: broken Value")
			}
			m := &it.methods[i]
			if m.pkgPath != nil {
				iv.flag |= flagRO
			}
			iv.typ = toCommonType(m.typ)
			iface := (*nonEmptyInterface)(iv.addr)
			if iface.itab == nil {
				iv.word = 0
				iv.nilmethod = true
			} else {
				iv.word = iword(iface.itab.fun[i])
			}
			iv.rcvr = iface.word
		} else {
			ut := iv.typ.uncommon()
			if ut == nil || i < 0 || i >= len(ut.methods) {
				panic("reflect: broken Value")
			}
			m := &ut.methods[i]
			if m.pkgPath != nil {
				iv.flag |= flagRO
			}
			iv.typ = toCommonType(m.mtyp)
			iv.rcvr = iv.word
			iv.word = iword(m.ifn)
		}
		iv.kind = Func
		iv.method = true
		iv.flag &^= flagAddr
		iv.addr = nil
	}

	return iv
}

// packValue returns a Value with the given flag bits, type, and interface word.
func packValue(flag uint32, typ *runtime.Type, word iword) Value {
	if typ == nil {
		panic("packValue")
	}
	t := uintptr(unsafe.Pointer(typ))
	t |= uintptr(flag)
	eface := emptyInterface{(*runtime.Type)(unsafe.Pointer(t)), word}
	return Value{Internal: *(*interface{})(unsafe.Pointer(&eface))}
}

// valueFromAddr returns a Value using the given type and address.
func valueFromAddr(flag uint32, typ Type, addr unsafe.Pointer) Value {
	if flag&flagAddr != 0 {
		// Addressable, so the internal value is
		// an interface containing a pointer to the real value.
		return packValue(flag, PtrTo(typ).runtimeType(), iword(addr))
	}

	var w iword
	if n := typ.Size(); n <= ptrSize {
		// In line, so the interface word is the actual value.
		w = loadIword(addr, n)
	} else {
		// Not in line: the interface word is the address.
		w = iword(addr)
	}
	return packValue(flag, typ.runtimeType(), w)
}

// valueFromIword returns a Value using the given type and interface word.
func valueFromIword(flag uint32, typ Type, w iword) Value {
	if flag&flagAddr != 0 {
		panic("reflect: internal error: valueFromIword addressable")
	}
	return packValue(flag, typ.runtimeType(), w)
}

func (iv internalValue) mustBe(want Kind) {
	if iv.kind != want {
		panic(&ValueError{methodName(), iv.kind})
	}
}

func (iv internalValue) mustBeExported() {
	if iv.kind == 0 {
		panic(&ValueError{methodName(), iv.kind})
	}
	if iv.flag&flagRO != 0 {
		panic(methodName() + " using value obtained using unexported field")
	}
}

func (iv internalValue) mustBeAssignable() {
	if iv.kind == 0 {
		panic(&ValueError{methodName(), iv.kind})
	}
	// Assignable if addressable and not read-only.
	if iv.flag&flagRO != 0 {
		panic(methodName() + " using value obtained using unexported field")
	}
	if iv.flag&flagAddr == 0 {
		panic(methodName() + " using unaddressable value")
	}
}

// Addr returns a pointer value representing the address of v.
// It panics if CanAddr() returns false.
// Addr is typically used to obtain a pointer to a struct field
// or slice element in order to call a method that requires a
// pointer receiver.
func (v Value) Addr() Value {
	iv := v.internal()
	if iv.flag&flagAddr == 0 {
		panic("reflect.Value.Addr of unaddressable value")
	}
	return valueFromIword(iv.flag&flagRO, PtrTo(iv.typ.toType()), iword(iv.addr))
}

// Bool returns v's underlying value.
// It panics if v's kind is not Bool.
func (v Value) Bool() bool {
	iv := v.internal()
	iv.mustBe(Bool)
	return *(*bool)(unsafe.Pointer(&iv.word))
}

// CanAddr returns true if the value's address can be obtained with Addr.
// Such values are called addressable.  A value is addressable if it is
// an element of a slice, an element of an addressable array,
// a field of an addressable struct, or the result of dereferencing a pointer.
// If CanAddr returns false, calling Addr will panic.
func (v Value) CanAddr() bool {
	iv := v.internal()
	return iv.flag&flagAddr != 0
}

// CanSet returns true if the value of v can be changed.
// A Value can be changed only if it is addressable and was not
// obtained by the use of unexported struct fields.
// If CanSet returns false, calling Set or any type-specific
// setter (e.g., SetBool, SetInt64) will panic.
func (v Value) CanSet() bool {
	iv := v.internal()
	return iv.flag&(flagAddr|flagRO) == flagAddr
}

// Call calls the function v with the input arguments in.
// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
// Call panics if v's Kind is not Func.
// It returns the output results as Values.
// As in Go, each input argument must be assignable to the
// type of the function's corresponding input parameter.
// If v is a variadic function, Call creates the variadic slice parameter
// itself, copying in the corresponding values.
func (v Value) Call(in []Value) []Value {
	iv := v.internal()
	iv.mustBe(Func)
	iv.mustBeExported()
	return iv.call("Call", in)
}

// CallSlice calls the variadic function v with the input arguments in,
// assigning the slice in[len(in)-1] to v's final variadic argument.  
// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
// Call panics if v's Kind is not Func or if v is not variadic.
// It returns the output results as Values.
// As in Go, each input argument must be assignable to the
// type of the function's corresponding input parameter.
func (v Value) CallSlice(in []Value) []Value {
	iv := v.internal()
	iv.mustBe(Func)
	iv.mustBeExported()
	return iv.call("CallSlice", in)
}

func (iv internalValue) call(method string, in []Value) []Value {
	if iv.word == 0 {
		if iv.nilmethod {
			panic("reflect.Value.Call: call of method on nil interface value")
		}
		panic("reflect.Value.Call: call of nil function")
	}

	isSlice := method == "CallSlice"
	t := iv.typ
	n := t.NumIn()
	if isSlice {
		if !t.IsVariadic() {
			panic("reflect: CallSlice of non-variadic function")
		}
		if len(in) < n {
			panic("reflect: CallSlice with too few input arguments")
		}
		if len(in) > n {
			panic("reflect: CallSlice with too many input arguments")
		}
	} else {
		if t.IsVariadic() {
			n--
		}
		if len(in) < n {
			panic("reflect: Call with too few input arguments")
		}
		if !t.IsVariadic() && len(in) > n {
			panic("reflect: Call with too many input arguments")
		}
	}
	for _, x := range in {
		if x.Kind() == Invalid {
			panic("reflect: " + method + " using zero Value argument")
		}
	}
	for i := 0; i < n; i++ {
		if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
			panic("reflect: " + method + " using " + xt.String() + " as type " + targ.String())
		}
	}
	if !isSlice && t.IsVariadic() {
		// prepare slice for remaining values
		m := len(in) - n
		slice := MakeSlice(t.In(n), m, m)
		elem := t.In(n).Elem()
		for i := 0; i < m; i++ {
			x := in[n+i]
			if xt := x.Type(); !xt.AssignableTo(elem) {
				panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + method)
			}
			slice.Index(i).Set(x)
		}
		origIn := in
		in = make([]Value, n+1)
		copy(in[:n], origIn)
		in[n] = slice
	}

	nin := len(in)
	if nin != t.NumIn() {
		panic("reflect.Value.Call: wrong argument count")
	}
	nout := t.NumOut()

	// Compute arg size & allocate.
	// This computation is 5g/6g/8g-dependent
	// and probably wrong for gccgo, but so
	// is most of this function.
	size := uintptr(0)
	if iv.method {
		// extra word for interface value
		size += ptrSize
	}
	for i := 0; i < nin; i++ {
		tv := t.In(i)
		a := uintptr(tv.Align())
		size = (size + a - 1) &^ (a - 1)
		size += tv.Size()
	}
	size = (size + ptrSize - 1) &^ (ptrSize - 1)
	for i := 0; i < nout; i++ {
		tv := t.Out(i)
		a := uintptr(tv.Align())
		size = (size + a - 1) &^ (a - 1)
		size += tv.Size()
	}

	// size must be > 0 in order for &args[0] to be valid.
	// the argument copying is going to round it up to
	// a multiple of ptrSize anyway, so make it ptrSize to begin with.
	if size < ptrSize {
		size = ptrSize
	}

	// round to pointer size
	size = (size + ptrSize - 1) &^ (ptrSize - 1)

	// Copy into args.
	//
	// TODO(rsc): revisit when reference counting happens.
	// The values are holding up the in references for us,
	// but something must be done for the out references.
	// For now make everything look like a pointer by pretending
	// to allocate a []*int.
	args := make([]*int, size/ptrSize)
	ptr := uintptr(unsafe.Pointer(&args[0]))
	off := uintptr(0)
	if iv.method {
		// Hard-wired first argument.
		*(*iword)(unsafe.Pointer(ptr)) = iv.rcvr
		off = ptrSize
	}
	for i, v := range in {
		iv := v.internal()
		iv.mustBeExported()
		targ := t.In(i).(*commonType)
		a := uintptr(targ.align)
		off = (off + a - 1) &^ (a - 1)
		n := targ.size
		addr := unsafe.Pointer(ptr + off)
		iv = convertForAssignment("reflect.Value.Call", addr, targ, iv)
		if iv.addr == nil {
			storeIword(addr, iv.word, n)
		} else {
			memmove(addr, iv.addr, n)
		}
		off += n
	}
	off = (off + ptrSize - 1) &^ (ptrSize - 1)

	// Call.
	call(unsafe.Pointer(iv.word), unsafe.Pointer(ptr), uint32(size))

	// Copy return values out of args.
	//
	// TODO(rsc): revisit like above.
	ret := make([]Value, nout)
	for i := 0; i < nout; i++ {
		tv := t.Out(i)
		a := uintptr(tv.Align())
		off = (off + a - 1) &^ (a - 1)
		ret[i] = valueFromAddr(0, tv, unsafe.Pointer(ptr+off))
		off += tv.Size()
	}

	return ret
}

// Cap returns v's capacity.
// It panics if v's Kind is not Array, Chan, or Slice.
func (v Value) Cap() int {
	iv := v.internal()
	switch iv.kind {
	case Array:
		return iv.typ.Len()
	case Chan:
		return int(chancap(iv.word))
	case Slice:
		return (*SliceHeader)(iv.addr).Cap
	}
	panic(&ValueError{"reflect.Value.Cap", iv.kind})
}

// Close closes the channel v.
// It panics if v's Kind is not Chan.
func (v Value) Close() {
	iv := v.internal()
	iv.mustBe(Chan)
	iv.mustBeExported()
	ch := iv.word
	chanclose(ch)
}

// Complex returns v's underlying value, as a complex128.
// It panics if v's Kind is not Complex64 or Complex128
func (v Value) Complex() complex128 {
	iv := v.internal()
	switch iv.kind {
	case Complex64:
		if iv.addr == nil {
			return complex128(*(*complex64)(unsafe.Pointer(&iv.word)))
		}
		return complex128(*(*complex64)(iv.addr))
	case Complex128:
		return *(*complex128)(iv.addr)
	}
	panic(&ValueError{"reflect.Value.Complex", iv.kind})
}

// Elem returns the value that the interface v contains
// or that the pointer v points to.
// It panics if v's Kind is not Interface or Ptr.
// It returns the zero Value if v is nil.
func (v Value) Elem() Value {
	iv := v.internal()
	return iv.Elem()
}

func (iv internalValue) Elem() Value {
	switch iv.kind {
	case Interface:
		// Empty interface and non-empty interface have different layouts.
		// Convert to empty interface.
		var eface emptyInterface
		if iv.typ.NumMethod() == 0 {
			eface = *(*emptyInterface)(iv.addr)
		} else {
			iface := (*nonEmptyInterface)(iv.addr)
			if iface.itab != nil {
				eface.typ = iface.itab.typ
			}
			eface.word = iface.word
		}
		if eface.typ == nil {
			return Value{}
		}
		return valueFromIword(iv.flag&flagRO, toType(eface.typ), eface.word)

	case Ptr:
		// The returned value's address is v's value.
		if iv.word == 0 {
			return Value{}
		}
		return valueFromAddr(iv.flag&flagRO|flagAddr, iv.typ.Elem(), unsafe.Pointer(iv.word))
	}
	panic(&ValueError{"reflect.Value.Elem", iv.kind})
}

// Field returns the i'th field of the struct v.
// It panics if v's Kind is not Struct or i is out of range.
func (v Value) Field(i int) Value {
	iv := v.internal()
	iv.mustBe(Struct)
	t := iv.typ.toType()
	if i < 0 || i >= t.NumField() {
		panic("reflect: Field index out of range")
	}
	f := t.Field(i)

	// Inherit permission bits from v.
	flag := iv.flag
	// Using an unexported field forces flagRO.
	if f.PkgPath != "" {
		flag |= flagRO
	}
	return valueFromValueOffset(flag, f.Type, iv, f.Offset)
}

// valueFromValueOffset returns a sub-value of outer
// (outer is an array or a struct) with the given flag and type
// starting at the given byte offset into outer.
func valueFromValueOffset(flag uint32, typ Type, outer internalValue, offset uintptr) Value {
	if outer.addr != nil {
		return valueFromAddr(flag, typ, unsafe.Pointer(uintptr(outer.addr)+offset))
	}

	// outer is so tiny it is in line.
	// We have to use outer.word and derive
	// the new word (it cannot possibly be bigger).
	// In line, so not addressable.
	if flag&flagAddr != 0 {
		panic("reflect: internal error: misuse of valueFromValueOffset")
	}
	b := *(*[ptrSize]byte)(unsafe.Pointer(&outer.word))
	for i := uintptr(0); i < typ.Size(); i++ {
		b[i] = b[offset+i]
	}
	for i := typ.Size(); i < ptrSize; i++ {
		b[i] = 0
	}
	w := *(*iword)(unsafe.Pointer(&b))
	return valueFromIword(flag, typ, w)
}

// FieldByIndex returns the nested field corresponding to index.
// It panics if v's Kind is not struct.
func (v Value) FieldByIndex(index []int) Value {
	v.internal().mustBe(Struct)
	for i, x := range index {
		if i > 0 {
			if v.Kind() == Ptr && v.Elem().Kind() == Struct {
				v = v.Elem()
			}
		}
		v = v.Field(x)
	}
	return v
}

// FieldByName returns the struct field with the given name.
// It returns the zero Value if no field was found.
// It panics if v's Kind is not struct.
func (v Value) FieldByName(name string) Value {
	iv := v.internal()
	iv.mustBe(Struct)
	if f, ok := iv.typ.FieldByName(name); ok {
		return v.FieldByIndex(f.Index)
	}
	return Value{}
}

// FieldByNameFunc returns the struct field with a name
// that satisfies the match function.
// It panics if v's Kind is not struct.
// It returns the zero Value if no field was found.
func (v Value) FieldByNameFunc(match func(string) bool) Value {
	v.internal().mustBe(Struct)
	if f, ok := v.Type().FieldByNameFunc(match); ok {
		return v.FieldByIndex(f.Index)
	}
	return Value{}
}

// Float returns v's underlying value, as an float64.
// It panics if v's Kind is not Float32 or Float64
func (v Value) Float() float64 {
	iv := v.internal()
	switch iv.kind {
	case Float32:
		return float64(*(*float32)(unsafe.Pointer(&iv.word)))
	case Float64:
		// If the pointer width can fit an entire float64,
		// the value is in line when stored in an interface.
		if iv.addr == nil {
			return *(*float64)(unsafe.Pointer(&iv.word))
		}
		// Otherwise we have a pointer.
		return *(*float64)(iv.addr)
	}
	panic(&ValueError{"reflect.Value.Float", iv.kind})
}

// Index returns v's i'th element.
// It panics if v's Kind is not Array or Slice or i is out of range.
func (v Value) Index(i int) Value {
	iv := v.internal()
	switch iv.kind {
	default:
		panic(&ValueError{"reflect.Value.Index", iv.kind})
	case Array:
		flag := iv.flag // element flag same as overall array
		t := iv.typ.toType()
		if i < 0 || i > t.Len() {
			panic("reflect: array index out of range")
		}
		typ := t.Elem()
		return valueFromValueOffset(flag, typ, iv, uintptr(i)*typ.Size())

	case Slice:
		// Element flag same as Elem of Ptr.
		// Addressable, possibly read-only.
		flag := iv.flag&flagRO | flagAddr
		s := (*SliceHeader)(iv.addr)
		if i < 0 || i >= s.Len {
			panic("reflect: slice index out of range")
		}
		typ := iv.typ.Elem()
		addr := unsafe.Pointer(s.Data + uintptr(i)*typ.Size())
		return valueFromAddr(flag, typ, addr)
	}

	panic("not reached")
}

// Int returns v's underlying value, as an int64.
// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
func (v Value) Int() int64 {
	iv := v.internal()
	switch iv.kind {
	case Int:
		return int64(*(*int)(unsafe.Pointer(&iv.word)))
	case Int8:
		return int64(*(*int8)(unsafe.Pointer(&iv.word)))
	case Int16:
		return int64(*(*int16)(unsafe.Pointer(&iv.word)))
	case Int32:
		return int64(*(*int32)(unsafe.Pointer(&iv.word)))
	case Int64:
		if iv.addr == nil {
			return *(*int64)(unsafe.Pointer(&iv.word))
		}
		return *(*int64)(iv.addr)
	}
	panic(&ValueError{"reflect.Value.Int", iv.kind})
}

// CanInterface returns true if Interface can be used without panicking.
func (v Value) CanInterface() bool {
	iv := v.internal()
	if iv.kind == Invalid {
		panic(&ValueError{"reflect.Value.CanInterface", iv.kind})
	}
	return v.InternalMethod == 0 && iv.flag&flagRO == 0
}

// Interface returns v's value as an interface{}.
// If v is a method obtained by invoking Value.Method
// (as opposed to Type.Method), Interface cannot return an
// interface value, so it panics.
func (v Value) Interface() interface{} {
	return valueInterface(v, true)
}

func valueInterface(v Value, safe bool) interface{} {
	iv := v.internal()
	return iv.valueInterface(safe)
}

func (iv internalValue) valueInterface(safe bool) interface{} {
	if iv.method {
		panic("reflect.Value.Interface: cannot create interface value for method with bound receiver")
	}

	if safe && iv.flag&flagRO != 0 {
		// Do not allow access to unexported values via Interface,
		// because they might be pointers that should not be 
		// writable or methods or function that should not be callable.
		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
	}
	if iv.kind == Interface {
		// Special case: return the element inside the interface.
		// Won't recurse further because an interface cannot contain an interface.
		if iv.IsNil() {
			return nil
		}
		return iv.Elem().Interface()
	}

	// Non-interface value.
	var eface emptyInterface
	eface.typ = iv.typ.runtimeType()
	eface.word = iv.word
	return *(*interface{})(unsafe.Pointer(&eface))
}

// InterfaceData returns the interface v's value as a uintptr pair.
// It panics if v's Kind is not Interface.
func (v Value) InterfaceData() [2]uintptr {
	iv := v.internal()
	iv.mustBe(Interface)
	// We treat this as a read operation, so we allow
	// it even for unexported data, because the caller
	// has to import "unsafe" to turn it into something
	// that can be abused.
	return *(*[2]uintptr)(iv.addr)
}

// IsNil returns true if v is a nil value.
// It panics if v's Kind is not Chan, Func, Interface, Map, Ptr, or Slice.
func (v Value) IsNil() bool {
	return v.internal().IsNil()
}

func (iv internalValue) IsNil() bool {
	switch iv.kind {
	case Chan, Func, Map, Ptr:
		if iv.method {
			panic("reflect: IsNil of method Value")
		}
		return iv.word == 0
	case Interface, Slice:
		// Both interface and slice are nil if first word is 0.
		return *(*uintptr)(iv.addr) == 0
	}
	panic(&ValueError{"reflect.Value.IsNil", iv.kind})
}

// IsValid returns true if v represents a value.
// It returns false if v is the zero Value.
// If IsValid returns false, all other methods except String panic.
// Most functions and methods never return an invalid value.
// If one does, its documentation states the conditions explicitly.
func (v Value) IsValid() bool {
	return v.Internal != nil
}

// Kind returns v's Kind.
// If v is the zero Value (IsValid returns false), Kind returns Invalid.
func (v Value) Kind() Kind {
	return v.internal().kind
}

// Len returns v's length.
// It panics if v's Kind is not Array, Chan, Map, or Slice.
func (v Value) Len() int {
	iv := v.internal()
	switch iv.kind {
	case Array:
		return iv.typ.Len()
	case Chan:
		return int(chanlen(iv.word))
	case Map:
		return int(maplen(iv.word))
	case Slice:
		return (*SliceHeader)(iv.addr).Len
	}
	panic(&ValueError{"reflect.Value.Len", iv.kind})
}

// MapIndex returns the value associated with key in the map v.
// It panics if v's Kind is not Map.
// It returns the zero Value if key is not found in the map or if v represents a nil map.
// As in Go, the key's value must be assignable to the map's key type.
func (v Value) MapIndex(key Value) Value {
	iv := v.internal()
	iv.mustBe(Map)
	typ := iv.typ.toType()

	// Do not require ikey to be exported, so that DeepEqual
	// and other programs can use all the keys returned by
	// MapKeys as arguments to MapIndex.  If either the map
	// or the key is unexported, though, the result will be
	// considered unexported.

	ikey := key.internal()
	ikey = convertForAssignment("reflect.Value.MapIndex", nil, typ.Key(), ikey)
	if iv.word == 0 {
		return Value{}
	}

	flag := (iv.flag | ikey.flag) & flagRO
	elemType := typ.Elem()
	elemWord, ok := mapaccess(iv.word, ikey.word)
	if !ok {
		return Value{}
	}
	return valueFromIword(flag, elemType, elemWord)
}

// MapKeys returns a slice containing all the keys present in the map,
// in unspecified order.
// It panics if v's Kind is not Map.
// It returns an empty slice if v represents a nil map.
func (v Value) MapKeys() []Value {
	iv := v.internal()
	iv.mustBe(Map)
	keyType := iv.typ.Key()

	flag := iv.flag & flagRO
	m := iv.word
	mlen := int32(0)
	if m != 0 {
		mlen = maplen(m)
	}
	it := mapiterinit(m)
	a := make([]Value, mlen)
	var i int
	for i = 0; i < len(a); i++ {
		keyWord, ok := mapiterkey(it)
		if !ok {
			break
		}
		a[i] = valueFromIword(flag, keyType, keyWord)
		mapiternext(it)
	}
	return a[:i]
}

// Method returns a function value corresponding to v's i'th method.
// The arguments to a Call on the returned function should not include
// a receiver; the returned function will always use v as the receiver.
// Method panics if i is out of range.
func (v Value) Method(i int) Value {
	iv := v.internal()
	if iv.kind == Invalid {
		panic(&ValueError{"reflect.Value.Method", Invalid})
	}
	if i < 0 || i >= iv.typ.NumMethod() {
		panic("reflect: Method index out of range")
	}
	return Value{v.Internal, i + 1}
}

// NumField returns the number of fields in the struct v.
// It panics if v's Kind is not Struct.
func (v Value) NumField() int {
	iv := v.internal()
	iv.mustBe(Struct)
	return iv.typ.NumField()
}

// OverflowComplex returns true if the complex128 x cannot be represented by v's type.
// It panics if v's Kind is not Complex64 or Complex128.
func (v Value) OverflowComplex(x complex128) bool {
	iv := v.internal()
	switch iv.kind {
	case Complex64:
		return overflowFloat32(real(x)) || overflowFloat32(imag(x))
	case Complex128:
		return false
	}
	panic(&ValueError{"reflect.Value.OverflowComplex", iv.kind})
}

// OverflowFloat returns true if the float64 x cannot be represented by v's type.
// It panics if v's Kind is not Float32 or Float64.
func (v Value) OverflowFloat(x float64) bool {
	iv := v.internal()
	switch iv.kind {
	case Float32:
		return overflowFloat32(x)
	case Float64:
		return false
	}
	panic(&ValueError{"reflect.Value.OverflowFloat", iv.kind})
}

func overflowFloat32(x float64) bool {
	if x < 0 {
		x = -x
	}
	return math.MaxFloat32 <= x && x <= math.MaxFloat64
}

// OverflowInt returns true if the int64 x cannot be represented by v's type.
// It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
func (v Value) OverflowInt(x int64) bool {
	iv := v.internal()
	switch iv.kind {
	case Int, Int8, Int16, Int32, Int64:
		bitSize := iv.typ.size * 8
		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
		return x != trunc
	}
	panic(&ValueError{"reflect.Value.OverflowInt", iv.kind})
}

// OverflowUint returns true if the uint64 x cannot be represented by v's type.
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
func (v Value) OverflowUint(x uint64) bool {
	iv := v.internal()
	switch iv.kind {
	case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
		bitSize := iv.typ.size * 8
		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
		return x != trunc
	}
	panic(&ValueError{"reflect.Value.OverflowUint", iv.kind})
}

// Pointer returns v's value as a uintptr.
// It returns uintptr instead of unsafe.Pointer so that
// code using reflect cannot obtain unsafe.Pointers
// without importing the unsafe package explicitly.
// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
func (v Value) Pointer() uintptr {
	iv := v.internal()
	switch iv.kind {
	case Chan, Func, Map, Ptr, UnsafePointer:
		if iv.kind == Func && v.InternalMethod != 0 {
			panic("reflect.Value.Pointer of method Value")
		}
		return uintptr(iv.word)
	case Slice:
		return (*SliceHeader)(iv.addr).Data
	}
	panic(&ValueError{"reflect.Value.Pointer", iv.kind})
}

// Recv receives and returns a value from the channel v.
// It panics if v's Kind is not Chan.
// The receive blocks until a value is ready.
// The boolean value ok is true if the value x corresponds to a send
// on the channel, false if it is a zero value received because the channel is closed.
func (v Value) Recv() (x Value, ok bool) {
	iv := v.internal()
	iv.mustBe(Chan)
	iv.mustBeExported()
	return iv.recv(false)
}

// internal recv, possibly non-blocking (nb)
func (iv internalValue) recv(nb bool) (val Value, ok bool) {
	t := iv.typ.toType()
	if t.ChanDir()&RecvDir == 0 {
		panic("recv on send-only channel")
	}
	ch := iv.word
	if ch == 0 {
		panic("recv on nil channel")
	}
	valWord, selected, ok := chanrecv(ch, nb)
	if selected {
		val = valueFromIword(0, t.Elem(), valWord)
	}
	return
}

// Send sends x on the channel v.
// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
// As in Go, x's value must be assignable to the channel's element type.
func (v Value) Send(x Value) {
	iv := v.internal()
	iv.mustBe(Chan)
	iv.mustBeExported()
	iv.send(x, false)
}

// internal send, possibly non-blocking
func (iv internalValue) send(x Value, nb bool) (selected bool) {
	t := iv.typ.toType()
	if t.ChanDir()&SendDir == 0 {
		panic("send on recv-only channel")
	}
	ix := x.internal()
	ix.mustBeExported() // do not let unexported x leak
	ix = convertForAssignment("reflect.Value.Send", nil, t.Elem(), ix)
	ch := iv.word
	if ch == 0 {
		panic("send on nil channel")
	}
	return chansend(ch, ix.word, nb)
}

// Set assigns x to the value v.
// It panics if CanSet returns false.
// As in Go, x's value must be assignable to v's type.
func (v Value) Set(x Value) {
	iv := v.internal()
	ix := x.internal()

	iv.mustBeAssignable()
	ix.mustBeExported() // do not let unexported x leak

	ix = convertForAssignment("reflect.Set", iv.addr, iv.typ, ix)

	n := ix.typ.size
	if n <= ptrSize {
		storeIword(iv.addr, ix.word, n)
	} else {
		memmove(iv.addr, ix.addr, n)
	}
}

// SetBool sets v's underlying value.
// It panics if v's Kind is not Bool or if CanSet() is false.
func (v Value) SetBool(x bool) {
	iv := v.internal()
	iv.mustBeAssignable()
	iv.mustBe(Bool)
	*(*bool)(iv.addr) = x
}

// SetComplex sets v's underlying value to x.
// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
func (v Value) SetComplex(x complex128) {
	iv := v.internal()
	iv.mustBeAssignable()
	switch iv.kind {
	default:
		panic(&ValueError{"reflect.Value.SetComplex", iv.kind})
	case Complex64:
		*(*complex64)(iv.addr) = complex64(x)
	case Complex128:
		*(*complex128)(iv.addr) = x
	}
}

// SetFloat sets v's underlying value to x.
// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
func (v Value) SetFloat(x float64) {
	iv := v.internal()
	iv.mustBeAssignable()
	switch iv.kind {
	default:
		panic(&ValueError{"reflect.Value.SetFloat", iv.kind})
	case Float32:
		*(*float32)(iv.addr) = float32(x)
	case Float64:
		*(*float64)(iv.addr) = x
	}
}

// SetInt sets v's underlying value to x.
// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
func (v Value) SetInt(x int64) {
	iv := v.internal()
	iv.mustBeAssignable()
	switch iv.kind {
	default:
		panic(&ValueError{"reflect.Value.SetInt", iv.kind})
	case Int:
		*(*int)(iv.addr) = int(x)
	case Int8:
		*(*int8)(iv.addr) = int8(x)
	case Int16:
		*(*int16)(iv.addr) = int16(x)
	case Int32:
		*(*int32)(iv.addr) = int32(x)
	case Int64:
		*(*int64)(iv.addr) = x
	}
}

// SetLen sets v's length to n.
// It panics if v's Kind is not Slice.
func (v Value) SetLen(n int) {
	iv := v.internal()
	iv.mustBeAssignable()
	iv.mustBe(Slice)
	s := (*SliceHeader)(iv.addr)
	if n < 0 || n > int(s.Cap) {
		panic("reflect: slice length out of range in SetLen")
	}
	s.Len = n
}

// SetMapIndex sets the value associated with key in the map v to val.
// It panics if v's Kind is not Map.
// If val is the zero Value, SetMapIndex deletes the key from the map.
// As in Go, key's value must be assignable to the map's key type,
// and val's value must be assignable to the map's value type.
func (v Value) SetMapIndex(key, val Value) {
	iv := v.internal()
	ikey := key.internal()
	ival := val.internal()

	iv.mustBe(Map)
	iv.mustBeExported()

	ikey.mustBeExported()
	ikey = convertForAssignment("reflect.Value.SetMapIndex", nil, iv.typ.Key(), ikey)

	if ival.kind != Invalid {
		ival.mustBeExported()
		ival = convertForAssignment("reflect.Value.SetMapIndex", nil, iv.typ.Elem(), ival)
	}

	mapassign(iv.word, ikey.word, ival.word, ival.kind != Invalid)
}

// SetUint sets v's underlying value to x.
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
func (v Value) SetUint(x uint64) {
	iv := v.internal()
	iv.mustBeAssignable()
	switch iv.kind {
	default:
		panic(&ValueError{"reflect.Value.SetUint", iv.kind})
	case Uint:
		*(*uint)(iv.addr) = uint(x)
	case Uint8:
		*(*uint8)(iv.addr) = uint8(x)
	case Uint16:
		*(*uint16)(iv.addr) = uint16(x)
	case Uint32:
		*(*uint32)(iv.addr) = uint32(x)
	case Uint64:
		*(*uint64)(iv.addr) = x
	case Uintptr:
		*(*uintptr)(iv.addr) = uintptr(x)
	}
}

// SetPointer sets the unsafe.Pointer value v to x.
// It panics if v's Kind is not UnsafePointer.
func (v Value) SetPointer(x unsafe.Pointer) {
	iv := v.internal()
	iv.mustBeAssignable()
	iv.mustBe(UnsafePointer)
	*(*unsafe.Pointer)(iv.addr) = x
}

// SetString sets v's underlying value to x.
// It panics if v's Kind is not String or if CanSet() is false.
func (v Value) SetString(x string) {
	iv := v.internal()
	iv.mustBeAssignable()
	iv.mustBe(String)
	*(*string)(iv.addr) = x
}

// Slice returns a slice of v.
// It panics if v's Kind is not Array or Slice.
func (v Value) Slice(beg, end int) Value {
	iv := v.internal()
	if iv.kind != Array && iv.kind != Slice {
		panic(&ValueError{"reflect.Value.Slice", iv.kind})
	}
	cap := v.Cap()
	if beg < 0 || end < beg || end > cap {
		panic("reflect.Value.Slice: slice index out of bounds")
	}
	var typ Type
	var base uintptr
	switch iv.kind {
	case Array:
		if iv.flag&flagAddr == 0 {
			panic("reflect.Value.Slice: slice of unaddressable array")
		}
		typ = toType((*arrayType)(unsafe.Pointer(iv.typ)).slice)
		base = uintptr(iv.addr)
	case Slice:
		typ = iv.typ.toType()
		base = (*SliceHeader)(iv.addr).Data
	}
	s := new(SliceHeader)
	s.Data = base + uintptr(beg)*typ.Elem().Size()
	s.Len = end - beg
	s.Cap = cap - beg
	return valueFromAddr(iv.flag&flagRO, typ, unsafe.Pointer(s))
}

// String returns the string v's underlying value, as a string.
// String is a special case because of Go's String method convention.
// Unlike the other getters, it does not panic if v's Kind is not String.
// Instead, it returns a string of the form "<T value>" where T is v's type.
func (v Value) String() string {
	iv := v.internal()
	switch iv.kind {
	case Invalid:
		return "<invalid Value>"
	case String:
		return *(*string)(iv.addr)
	}
	return "<" + iv.typ.String() + " Value>"
}

// TryRecv attempts to receive a value from the channel v but will not block.
// It panics if v's Kind is not Chan.
// If the receive cannot finish without blocking, x is the zero Value.
// The boolean ok is true if the value x corresponds to a send
// on the channel, false if it is a zero value received because the channel is closed.
func (v Value) TryRecv() (x Value, ok bool) {
	iv := v.internal()
	iv.mustBe(Chan)
	iv.mustBeExported()
	return iv.recv(true)
}

// TrySend attempts to send x on the channel v but will not block.
// It panics if v's Kind is not Chan.
// It returns true if the value was sent, false otherwise.
// As in Go, x's value must be assignable to the channel's element type.
func (v Value) TrySend(x Value) bool {
	iv := v.internal()
	iv.mustBe(Chan)
	iv.mustBeExported()
	return iv.send(x, true)
}

// Type returns v's type.
func (v Value) Type() Type {
	t := v.internal().typ
	if t == nil {
		panic(&ValueError{"reflect.Value.Type", Invalid})
	}
	return t.toType()
}

// Uint returns v's underlying value, as a uint64.
// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
func (v Value) Uint() uint64 {
	iv := v.internal()
	switch iv.kind {
	case Uint:
		return uint64(*(*uint)(unsafe.Pointer(&iv.word)))
	case Uint8:
		return uint64(*(*uint8)(unsafe.Pointer(&iv.word)))
	case Uint16:
		return uint64(*(*uint16)(unsafe.Pointer(&iv.word)))
	case Uint32:
		return uint64(*(*uint32)(unsafe.Pointer(&iv.word)))
	case Uintptr:
		return uint64(*(*uintptr)(unsafe.Pointer(&iv.word)))
	case Uint64:
		if iv.addr == nil {
			return *(*uint64)(unsafe.Pointer(&iv.word))
		}
		return *(*uint64)(iv.addr)
	}
	panic(&ValueError{"reflect.Value.Uint", iv.kind})
}

// UnsafeAddr returns a pointer to v's data.
// It is for advanced clients that also import the "unsafe" package.
// It panics if v is not addressable.
func (v Value) UnsafeAddr() uintptr {
	iv := v.internal()
	if iv.kind == Invalid {
		panic(&ValueError{"reflect.Value.UnsafeAddr", iv.kind})
	}
	if iv.flag&flagAddr == 0 {
		panic("reflect.Value.UnsafeAddr of unaddressable value")
	}
	return uintptr(iv.addr)
}

// StringHeader is the runtime representation of a string.
// It cannot be used safely or portably.
type StringHeader struct {
	Data uintptr
	Len  int
}

// SliceHeader is the runtime representation of a slice.
// It cannot be used safely or portably.
type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}

func typesMustMatch(what string, t1, t2 Type) {
	if t1 != t2 {
		panic("reflect: " + what + ": " + t1.String() + " != " + t2.String())
	}
}

// grow grows the slice s so that it can hold extra more values, allocating
// more capacity if needed. It also returns the old and new slice lengths.
func grow(s Value, extra int) (Value, int, int) {
	i0 := s.Len()
	i1 := i0 + extra
	if i1 < i0 {
		panic("reflect.Append: slice overflow")
	}
	m := s.Cap()
	if i1 <= m {
		return s.Slice(0, i1), i0, i1
	}
	if m == 0 {
		m = extra
	} else {
		for m < i1 {
			if i0 < 1024 {
				m += m
			} else {
				m += m / 4
			}
		}
	}
	t := MakeSlice(s.Type(), i1, m)
	Copy(t, s)
	return t, i0, i1
}

// Append appends the values x to a slice s and returns the resulting slice.
// As in Go, each x's value must be assignable to the slice's element type.
func Append(s Value, x ...Value) Value {
	s.internal().mustBe(Slice)
	s, i0, i1 := grow(s, len(x))
	for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
		s.Index(i).Set(x[j])
	}
	return s
}

// AppendSlice appends a slice t to a slice s and returns the resulting slice.
// The slices s and t must have the same element type.
func AppendSlice(s, t Value) Value {
	s.internal().mustBe(Slice)
	t.internal().mustBe(Slice)
	typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
	s, i0, i1 := grow(s, t.Len())
	Copy(s.Slice(i0, i1), t)
	return s
}

// Copy copies the contents of src into dst until either
// dst has been filled or src has been exhausted.
// It returns the number of elements copied.
// Dst and src each must have kind Slice or Array, and
// dst and src must have the same element type.
func Copy(dst, src Value) int {
	idst := dst.internal()
	isrc := src.internal()

	if idst.kind != Array && idst.kind != Slice {
		panic(&ValueError{"reflect.Copy", idst.kind})
	}
	if idst.kind == Array {
		idst.mustBeAssignable()
	}
	idst.mustBeExported()
	if isrc.kind != Array && isrc.kind != Slice {
		panic(&ValueError{"reflect.Copy", isrc.kind})
	}
	isrc.mustBeExported()

	de := idst.typ.Elem()
	se := isrc.typ.Elem()
	typesMustMatch("reflect.Copy", de, se)

	n := dst.Len()
	if sn := src.Len(); n > sn {
		n = sn
	}

	// If sk is an in-line array, cannot take its address.
	// Instead, copy element by element.
	if isrc.addr == nil {
		for i := 0; i < n; i++ {
			dst.Index(i).Set(src.Index(i))
		}
		return n
	}

	// Copy via memmove.
	var da, sa unsafe.Pointer
	if idst.kind == Array {
		da = idst.addr
	} else {
		da = unsafe.Pointer((*SliceHeader)(idst.addr).Data)
	}
	if isrc.kind == Array {
		sa = isrc.addr
	} else {
		sa = unsafe.Pointer((*SliceHeader)(isrc.addr).Data)
	}
	memmove(da, sa, uintptr(n)*de.Size())
	return n
}

/*
 * constructors
 */

// MakeSlice creates a new zero-initialized slice value
// for the specified slice type, length, and capacity.
func MakeSlice(typ Type, len, cap int) Value {
	if typ.Kind() != Slice {
		panic("reflect: MakeSlice of non-slice type")
	}
	s := &SliceHeader{
		Data: uintptr(unsafe.NewArray(typ.Elem(), cap)),
		Len:  len,
		Cap:  cap,
	}
	return valueFromAddr(0, typ, unsafe.Pointer(s))
}

// MakeChan creates a new channel with the specified type and buffer size.
func MakeChan(typ Type, buffer int) Value {
	if typ.Kind() != Chan {
		panic("reflect: MakeChan of non-chan type")
	}
	if buffer < 0 {
		panic("MakeChan: negative buffer size")
	}
	if typ.ChanDir() != BothDir {
		panic("MakeChan: unidirectional channel type")
	}
	ch := makechan(typ.runtimeType(), uint32(buffer))
	return valueFromIword(0, typ, ch)
}

// MakeMap creates a new map of the specified type.
func MakeMap(typ Type) Value {
	if typ.Kind() != Map {
		panic("reflect: MakeMap of non-map type")
	}
	m := makemap(typ.runtimeType())
	return valueFromIword(0, typ, m)
}

// Indirect returns the value that v points to.
// If v is a nil pointer, Indirect returns a nil Value.
// If v is not a pointer, Indirect returns v.
func Indirect(v Value) Value {
	if v.Kind() != Ptr {
		return v
	}
	return v.Elem()
}

// ValueOf returns a new Value initialized to the concrete value
// stored in the interface i.  ValueOf(nil) returns the zero Value.
func ValueOf(i interface{}) Value {
	if i == nil {
		return Value{}
	}
	// For an interface value with the noAddr bit set,
	// the representation is identical to an empty interface.
	eface := *(*emptyInterface)(unsafe.Pointer(&i))
	return packValue(0, eface.typ, eface.word)
}

// Zero returns a Value representing a zero value for the specified type.
// The result is different from the zero value of the Value struct,
// which represents no value at all.
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
func Zero(typ Type) Value {
	if typ == nil {
		panic("reflect: Zero(nil)")
	}
	if typ.Size() <= ptrSize {
		return valueFromIword(0, typ, 0)
	}
	return valueFromAddr(0, typ, unsafe.New(typ))
}

// New returns a Value representing a pointer to a new zero value
// for the specified type.  That is, the returned Value's Type is PtrTo(t).
func New(typ Type) Value {
	if typ == nil {
		panic("reflect: New(nil)")
	}
	ptr := unsafe.New(typ)
	return valueFromIword(0, PtrTo(typ), iword(ptr))
}

// convertForAssignment 
func convertForAssignment(what string, addr unsafe.Pointer, dst Type, iv internalValue) internalValue {
	if iv.method {
		panic(what + ": cannot assign method value to type " + dst.String())
	}

	dst1 := dst.(*commonType)
	if directlyAssignable(dst1, iv.typ) {
		// Overwrite type so that they match.
		// Same memory layout, so no harm done.
		iv.typ = dst1
		return iv
	}
	if implements(dst1, iv.typ) {
		if addr == nil {
			addr = unsafe.Pointer(new(interface{}))
		}
		x := iv.valueInterface(false)
		if dst.NumMethod() == 0 {
			*(*interface{})(addr) = x
		} else {
			ifaceE2I(dst1.runtimeType(), x, addr)
		}
		iv.addr = addr
		iv.word = iword(addr)
		iv.typ = dst1
		return iv
	}

	// Failed.
	panic(what + ": value of type " + iv.typ.String() + " is not assignable to type " + dst.String())
}

// implemented in ../pkg/runtime
func chancap(ch iword) int32
func chanclose(ch iword)
func chanlen(ch iword) int32
func chanrecv(ch iword, nb bool) (val iword, selected, received bool)
func chansend(ch iword, val iword, nb bool) bool

func makechan(typ *runtime.Type, size uint32) (ch iword)
func makemap(t *runtime.Type) iword
func mapaccess(m iword, key iword) (val iword, ok bool)
func mapassign(m iword, key, val iword, ok bool)
func mapiterinit(m iword) *byte
func mapiterkey(it *byte) (key iword, ok bool)
func mapiternext(it *byte)
func maplen(m iword) int32

func call(fn, arg unsafe.Pointer, n uint32)
func ifaceE2I(t *runtime.Type, src interface{}, dst unsafe.Pointer)
