OSDN Git Service

reflect: Fix invalid sharing in valueInterface.
[pf3gnuchains/gcc-fork.git] / libgo / go / reflect / value.go
index 8ef402b..5d08900 100644 (file)
@@ -7,17 +7,17 @@ package reflect
 import (
        "math"
        "runtime"
+       "strconv"
        "unsafe"
 )
 
-const ptrSize = uintptr(unsafe.Sizeof((*byte)(nil)))
-const cannotSet = "cannot set value obtained via unexported struct field"
-
-type addr unsafe.Pointer
+const bigEndian = false // can be smarter if we find a big-endian machine
+const ptrSize = 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 addr, n uintptr) {
+func memmove(adst, asrc unsafe.Pointer, n uintptr) {
        dst := uintptr(adst)
        src := uintptr(asrc)
        switch {
@@ -26,1217 +26,1783 @@ func memmove(adst, asrc addr, n uintptr) {
                // careful: i is unsigned
                for i := n; i > 0; {
                        i--
-                       *(*byte)(addr(dst + i)) = *(*byte)(addr(src + 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)(addr(dst + i)) = *(*byte)(addr(src + i))
+                       *(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
                }
        default:
                // word copy forward
                for i := uintptr(0); i < n; i += ptrSize {
-                       *(*uintptr)(addr(dst + i)) = *(*uintptr)(addr(src + i))
+                       *(*uintptr)(unsafe.Pointer(dst + i)) = *(*uintptr)(unsafe.Pointer(src + i))
                }
        }
 }
 
-// Value is the common interface to reflection values.
-// The implementations of Value (e.g., ArrayValue, StructValue)
-// have additional type-specific methods.
-type Value interface {
-       // Type returns the value's type.
-       Type() Type
-
-       // Interface returns the value as an interface{}.
-       Interface() interface{}
-
-       // CanSet returns whether the value can be changed.
-       // Values obtained by the use of non-exported struct fields
-       // can be used in Get but not Set.
-       // If CanSet() returns false, calling the type-specific Set
-       // will cause a crash.
-       CanSet() bool
-
-       // SetValue assigns v to the value; v must have the same type as the value.
-       SetValue(v Value)
-
-       // Addr returns a pointer to the underlying data.
-       // It is for advanced clients that also
-       // import the "unsafe" package.
-       Addr() uintptr
-
-       // Method returns a FuncValue corresponding to the value's i'th method.
-       // The arguments to a Call on the returned FuncValue
-       // should not include a receiver; the FuncValue will use
-       // the value as the receiver.
-       Method(i int) *FuncValue
+// 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.
+//
+// A Value can be used concurrently by multiple goroutines provided that
+// the underlying Go value can be used concurrently for the equivalent
+// direct operations.
+type Value struct {
+       // typ holds the type of the value represented by a Value.
+       typ *commonType
+
+       // val holds the 1-word representation of the value.
+       // If flag's flagIndir bit is set, then val is a pointer to the data.
+       // Otherwise val is a word holding the actual data.
+       // When the data is smaller than a word, it begins at
+       // the first byte (in the memory address sense) of val.
+       // We use unsafe.Pointer so that the garbage collector
+       // knows that val could be a pointer.
+       val unsafe.Pointer
+
+       // flag holds metadata about the value.
+       // The lowest bits are flag bits:
+       //      - flagRO: obtained via unexported field, so read-only
+       //      - flagIndir: val holds a pointer to the data
+       //      - flagAddr: v.CanAddr is true (implies flagIndir)
+       //      - flagMethod: v is a method value.
+       // The next five bits give the Kind of the value.
+       // This repeats typ.Kind() except for method values.
+       // The remaining 23+ bits give a method number for method values.
+       // If flag.kind() != Func, code can assume that flagMethod is unset.
+       // If typ.size > ptrSize, code can assume that flagIndir is set.
+       flag
+
+       // A method value represents a curried method invocation
+       // like r.Read for some receiver r.  The typ+val+flag bits describe
+       // the receiver r, but the flag's Kind bits say Func (methods are
+       // functions), and the top bits of the flag give the method number
+       // in r's type's method table.
+}
+
+type flag uintptr
+
+const (
+       flagRO flag = 1 << iota
+       flagIndir
+       flagAddr
+       flagMethod
+       flagKindShift        = iota
+       flagKindWidth        = 5 // there are 27 kinds
+       flagKindMask    flag = 1<<flagKindWidth - 1
+       flagMethodShift      = flagKindShift + flagKindWidth
+)
 
-       getAddr() addr
+func (f flag) kind() Kind {
+       return Kind((f >> flagKindShift) & flagKindMask)
 }
 
-// value is the common implementation of most values.
-// It is embedded in other, public struct types, but always
-// with a unique tag like "uint" or "float" so that the client cannot
-// convert from, say, *UintValue to *FloatValue.
-type value struct {
-       typ    Type
-       addr   addr
-       canSet bool
+// 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 (v *value) Type() Type { return v.typ }
+func (e *ValueError) Error() 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"
+}
 
-func (v *value) Addr() uintptr { return uintptr(v.addr) }
+// 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()
+}
 
-func (v *value) getAddr() addr { return v.addr }
+// 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 holds the data stored
+// in its leading bytes (so is not a pointer).
+// Because the value sometimes holds a pointer, we use
+// unsafe.Pointer to represent it, so that if iword appears
+// in a struct, the garbage collector knows that might be
+// a pointer.
+type iword unsafe.Pointer
 
-func (v *value) Interface() interface{} {
-       if typ, ok := v.typ.(*InterfaceType); ok {
-               // There are two different representations of interface values,
-               // one if the interface type has methods and one if it doesn't.
-               // These two representations require different expressions
-               // to extract correctly.
-               if typ.NumMethod() == 0 {
-                       // Extract as interface value without methods.
-                       return *(*interface{})(v.addr)
-               }
-               // Extract from v.addr as interface value with methods.
-               return *(*interface {
-                       m()
-               })(v.addr)
+func (v Value) iword() iword {
+       if v.flag&flagIndir != 0 && (v.kind() == Ptr || v.kind() == UnsafePointer) {
+               // Have indirect but want direct word.
+               return loadIword(v.val, v.typ.size)
        }
-       return unsafe.Unreflect(v.typ, unsafe.Pointer(v.addr))
+       return iword(v.val)
 }
 
-func (v *value) CanSet() bool { return v.canSet }
+// loadIword loads n bytes at p from memory into an iword.
+func loadIword(p unsafe.Pointer, n uintptr) iword {
+       // Run the copy ourselves instead of calling memmove
+       // to avoid moving w to the heap.
+       var w iword
+       switch n {
+       default:
+               panic("reflect: internal error: loadIword of " + strconv.Itoa(int(n)) + "-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
+}
+
+// storeIword stores n bytes from w into p.
+func storeIword(p unsafe.Pointer, w iword, n uintptr) {
+       // Run the copy ourselves instead of calling memmove
+       // to avoid moving w to the heap.
+       switch n {
+       default:
+               panic("reflect: internal error: storeIword of " + strconv.Itoa(int(n)) + "-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))
+       }
+}
 
-/*
- * basic types
- */
+// emptyInterface is the header for an interface{} value.
+type emptyInterface struct {
+       typ  *runtimeType
+       word iword
+}
 
-// BoolValue represents a bool value.
-type BoolValue struct {
-       value "bool"
+// nonEmptyInterface is the header for a interface value with methods.
+type nonEmptyInterface struct {
+       // see ../runtime/iface.c:/Itab
+       itab *struct {
+               typ *runtimeType           // dynamic concrete type
+               fun [100000]unsafe.Pointer // method table
+       }
+       word iword
+}
+
+// mustBe panics if f's kind is not expected.
+// Making this a method on flag instead of on Value
+// (and embedding flag in Value) means that we can write
+// the very clear v.mustBe(Bool) and have it compile into
+// v.flag.mustBe(Bool), which will only bother to copy the
+// single important word for the receiver.
+func (f flag) mustBe(expected Kind) {
+       k := f.kind()
+       if k != expected {
+               panic(&ValueError{methodName(), k})
+       }
+}
+
+// mustBeExported panics if f records that the value was obtained using
+// an unexported field.
+func (f flag) mustBeExported() {
+       if f == 0 {
+               panic(&ValueError{methodName(), 0})
+       }
+       if f&flagRO != 0 {
+               panic(methodName() + " using value obtained using unexported field")
+       }
+}
+
+// mustBeAssignable panics if f records that the value is not assignable,
+// which is to say that either it was obtained using an unexported field
+// or it is not addressable.
+func (f flag) mustBeAssignable() {
+       if f == 0 {
+               panic(&ValueError{methodName(), Invalid})
+       }
+       // Assignable if addressable and not read-only.
+       if f&flagRO != 0 {
+               panic(methodName() + " using value obtained using unexported field")
+       }
+       if f&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 {
+       if v.flag&flagAddr == 0 {
+               panic("reflect.Value.Addr of unaddressable value")
+       }
+       return Value{v.typ.ptrTo(), v.val, (v.flag & flagRO) | flag(Ptr)<<flagKindShift}
+}
+
+// Bool returns v's underlying value.
+// It panics if v's kind is not Bool.
+func (v Value) Bool() bool {
+       v.mustBe(Bool)
+       if v.flag&flagIndir != 0 {
+               return *(*bool)(v.val)
+       }
+       return *(*bool)(unsafe.Pointer(&v.val))
+}
+
+// Bytes returns v's underlying value.
+// It panics if v's underlying value is not a slice of bytes.
+func (v Value) Bytes() []byte {
+       v.mustBe(Slice)
+       if v.typ.Elem().Kind() != Uint8 {
+               panic("reflect.Value.Bytes of non-byte slice")
+       }
+       // Slice is always bigger than a word; assume flagIndir.
+       return *(*[]byte)(v.val)
+}
+
+// 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 {
+       return v.flag&flagAddr != 0
 }
 
-// Get returns the underlying bool value.
-func (v *BoolValue) Get() bool { return *(*bool)(v.addr) }
+// 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 {
+       return v.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 {
+       v.mustBe(Func)
+       v.mustBeExported()
+       return v.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 {
+       v.mustBe(Func)
+       v.mustBeExported()
+       return v.call("CallSlice", in)
+}
+
+func (v Value) call(method string, in []Value) []Value {
+       // Get function pointer, type.
+       t := v.typ
+       var (
+               fn   unsafe.Pointer
+               rcvr iword
+       )
+       if v.flag&flagMethod != 0 {
+               i := int(v.flag) >> flagMethodShift
+               if v.typ.Kind() == Interface {
+                       tt := (*interfaceType)(unsafe.Pointer(v.typ))
+                       if i < 0 || i >= len(tt.methods) {
+                               panic("reflect: broken Value")
+                       }
+                       m := &tt.methods[i]
+                       if m.pkgPath != nil {
+                               panic(method + " of unexported method")
+                       }
+                       t = toCommonType(m.typ)
+                       iface := (*nonEmptyInterface)(v.val)
+                       if iface.itab == nil {
+                               panic(method + " of method on nil interface value")
+                       }
+                       fn = iface.itab.fun[i]
+                       rcvr = iface.word
+               } else {
+                       ut := v.typ.uncommon()
+                       if ut == nil || i < 0 || i >= len(ut.methods) {
+                               panic("reflect: broken Value")
+                       }
+                       m := &ut.methods[i]
+                       if m.pkgPath != nil {
+                               panic(method + " of unexported method")
+                       }
+                       fn = m.tfn
+                       t = toCommonType(m.mtyp)
+                       rcvr = v.iword()
+               }
+       } else if v.flag&flagIndir != 0 {
+               fn = *(*unsafe.Pointer)(v.val)
+       } else {
+               fn = v.val
+       }
 
-// Set sets v to the value x.
-func (v *BoolValue) Set(x bool) {
-       if !v.canSet {
-               panic(cannotSet)
+       if fn == nil {
+               panic("reflect.Value.Call: call of nil function")
        }
-       *(*bool)(v.addr) = x
-}
 
-// Set sets v to the value x.
-func (v *BoolValue) SetValue(x Value) { v.Set(x.(*BoolValue).Get()) }
+       isSlice := method == "CallSlice"
+       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
+       }
 
-// FloatValue represents a float value.
-type FloatValue struct {
-       value "float"
-}
+       nin := len(in)
+       if nin != t.NumIn() {
+               panic("reflect.Value.Call: wrong argument count")
+       }
+       nout := t.NumOut()
 
-// Get returns the underlying int value.
-func (v *FloatValue) Get() float64 {
-       switch v.typ.Kind() {
-       case Float32:
-               return float64(*(*float32)(v.addr))
-       case Float64:
-               return *(*float64)(v.addr)
+       if v.flag&flagMethod != 0 {
+               nin++
+       }
+       params := make([]unsafe.Pointer, nin)
+       off := 0
+       if v.flag&flagMethod != 0 {
+               // Hard-wired first argument.
+               p := new(iword)
+               *p = rcvr
+               params[0] = unsafe.Pointer(p)
+               off = 1
+       }
+       first_pointer := false
+       for i, pv := range in {
+               pv.mustBeExported()
+               targ := t.In(i).(*commonType)
+               pv = pv.assignTo("reflect.Value.Call", targ, nil)
+               if pv.flag&flagIndir == 0 {
+                       p := new(unsafe.Pointer)
+                       *p = pv.val
+                       params[off] = unsafe.Pointer(p)
+               } else {
+                       params[off] = pv.val
+               }
+               if i == 0 && Kind(targ.kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) {
+                       p := new(unsafe.Pointer)
+                       *p = params[off]
+                       params[off] = unsafe.Pointer(p)
+                       first_pointer = true
+               }
+               off++
        }
-       panic("reflect: invalid float kind")
-}
 
-// Set sets v to the value x.
-func (v *FloatValue) Set(x float64) {
-       if !v.canSet {
-               panic(cannotSet)
+       ret := make([]Value, nout)
+       results := make([]unsafe.Pointer, nout)
+       for i := 0; i < nout; i++ {
+               v := New(t.Out(i))
+               results[i] = unsafe.Pointer(v.Pointer())
+               ret[i] = Indirect(v)
        }
-       switch v.typ.Kind() {
-       default:
-               panic("reflect: invalid float kind")
-       case Float32:
-               *(*float32)(v.addr) = float32(x)
-       case Float64:
-               *(*float64)(v.addr) = x
+
+       var pp *unsafe.Pointer
+       if len(params) > 0 {
+               pp = &params[0]
+       }
+       var pr *unsafe.Pointer
+       if len(results) > 0 {
+               pr = &results[0]
        }
+
+       call(t, fn, v.flag&flagMethod != 0, first_pointer, pp, pr)
+
+       return ret
 }
 
-// Overflow returns true if x cannot be represented by the type of v.
-func (v *FloatValue) Overflow(x float64) bool {
-       if v.typ.Size() == 8 {
+// gccgo specific test to see if typ is a method.  We can tell by
+// looking at the string to see if there is a receiver.  We need this
+// because for gccgo all methods take pointer receivers.
+func isMethod(t *commonType) bool {
+       if Kind(t.kind) != Func {
                return false
        }
-       if x < 0 {
-               x = -x
+       s := *t.string
+       parens := 0
+       params := 0
+       sawRet := false
+       for i, c := range s {
+               if c == '(' {
+                       parens++
+                       params++
+               } else if c == ')' {
+                       parens--
+               } else if parens == 0 && c == ' ' && s[i+1] != '(' && !sawRet {
+                       params++
+                       sawRet = true
+               }
        }
-       return math.MaxFloat32 < x && x <= math.MaxFloat64
+       return params > 2
 }
 
-// Set sets v to the value x.
-func (v *FloatValue) SetValue(x Value) { v.Set(x.(*FloatValue).Get()) }
+// Cap returns v's capacity.
+// It panics if v's Kind is not Array, Chan, or Slice.
+func (v Value) Cap() int {
+       k := v.kind()
+       switch k {
+       case Array:
+               return v.typ.Len()
+       case Chan:
+               return int(chancap(*(*iword)(v.iword())))
+       case Slice:
+               // Slice is always bigger than a word; assume flagIndir.
+               return (*SliceHeader)(v.val).Cap
+       }
+       panic(&ValueError{"reflect.Value.Cap", k})
+}
 
-// ComplexValue represents a complex value.
-type ComplexValue struct {
-       value "complex"
+// Close closes the channel v.
+// It panics if v's Kind is not Chan.
+func (v Value) Close() {
+       v.mustBe(Chan)
+       v.mustBeExported()
+       chanclose(*(*iword)(v.iword()))
 }
 
-// Get returns the underlying complex value.
-func (v *ComplexValue) Get() complex128 {
-       switch v.typ.Kind() {
+// 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 {
+       k := v.kind()
+       switch k {
        case Complex64:
-               return complex128(*(*complex64)(v.addr))
+               if v.flag&flagIndir != 0 {
+                       return complex128(*(*complex64)(v.val))
+               }
+               return complex128(*(*complex64)(unsafe.Pointer(&v.val)))
        case Complex128:
-               return *(*complex128)(v.addr)
+               // complex128 is always bigger than a word; assume flagIndir.
+               return *(*complex128)(v.val)
+       }
+       panic(&ValueError{"reflect.Value.Complex", k})
+}
+
+// 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 {
+       k := v.kind()
+       switch k {
+       case Interface:
+               var (
+                       typ *commonType
+                       val unsafe.Pointer
+               )
+               if v.typ.NumMethod() == 0 {
+                       eface := (*emptyInterface)(v.val)
+                       if eface.typ == nil {
+                               // nil interface value
+                               return Value{}
+                       }
+                       typ = toCommonType(eface.typ)
+                       val = unsafe.Pointer(eface.word)
+               } else {
+                       iface := (*nonEmptyInterface)(v.val)
+                       if iface.itab == nil {
+                               // nil interface value
+                               return Value{}
+                       }
+                       typ = toCommonType(iface.itab.typ)
+                       val = unsafe.Pointer(iface.word)
+               }
+               fl := v.flag & flagRO
+               fl |= flag(typ.Kind()) << flagKindShift
+               if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
+                       fl |= flagIndir
+               }
+               return Value{typ, val, fl}
+
+       case Ptr:
+               val := v.val
+               if v.flag&flagIndir != 0 {
+                       val = *(*unsafe.Pointer)(val)
+               }
+               // The returned value's address is v's value.
+               if val == nil {
+                       return Value{}
+               }
+               tt := (*ptrType)(unsafe.Pointer(v.typ))
+               typ := toCommonType(tt.elem)
+               fl := v.flag&flagRO | flagIndir | flagAddr
+               fl |= flag(typ.Kind() << flagKindShift)
+               return Value{typ, val, fl}
        }
-       panic("reflect: invalid complex kind")
+       panic(&ValueError{"reflect.Value.Elem", k})
 }
 
-// Set sets v to the value x.
-func (v *ComplexValue) Set(x complex128) {
-       if !v.canSet {
-               panic(cannotSet)
+// 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 {
+       v.mustBe(Struct)
+       tt := (*structType)(unsafe.Pointer(v.typ))
+       if i < 0 || i >= len(tt.fields) {
+               panic("reflect: Field index out of range")
+       }
+       field := &tt.fields[i]
+       typ := toCommonType(field.typ)
+
+       // Inherit permission bits from v.
+       fl := v.flag & (flagRO | flagIndir | flagAddr)
+       // Using an unexported field forces flagRO.
+       if field.pkgPath != nil {
+               fl |= flagRO
        }
-       switch v.typ.Kind() {
+       fl |= flag(typ.Kind()) << flagKindShift
+
+       var val unsafe.Pointer
+       switch {
+       case fl&flagIndir != 0:
+               // Indirect.  Just bump pointer.
+               val = unsafe.Pointer(uintptr(v.val) + field.offset)
+       case bigEndian:
+               // Direct.  Discard leading bytes.
+               val = unsafe.Pointer(uintptr(v.val) << (field.offset * 8))
        default:
-               panic("reflect: invalid complex kind")
-       case Complex64:
-               *(*complex64)(v.addr) = complex64(x)
-       case Complex128:
-               *(*complex128)(v.addr) = x
+               // Direct.  Discard leading bytes.
+               val = unsafe.Pointer(uintptr(v.val) >> (field.offset * 8))
        }
+
+       return Value{typ, val, fl}
 }
 
-// Set sets v to the value x.
-func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) }
+// 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.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
+}
 
-// IntValue represents an int value.
-type IntValue struct {
-       value "int"
+// 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 {
+       v.mustBe(Struct)
+       if f, ok := v.typ.FieldByName(name); ok {
+               return v.FieldByIndex(f.Index)
+       }
+       return Value{}
 }
 
-// Get returns the underlying int value.
-func (v *IntValue) Get() int64 {
-       switch v.typ.Kind() {
-       case Int:
-               return int64(*(*int)(v.addr))
-       case Int8:
-               return int64(*(*int8)(v.addr))
-       case Int16:
-               return int64(*(*int16)(v.addr))
-       case Int32:
-               return int64(*(*int32)(v.addr))
-       case Int64:
-               return *(*int64)(v.addr)
+// 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.mustBe(Struct)
+       if f, ok := v.typ.FieldByNameFunc(match); ok {
+               return v.FieldByIndex(f.Index)
        }
-       panic("reflect: invalid int kind")
+       return Value{}
 }
 
-// Set sets v to the value x.
-func (v *IntValue) Set(x int64) {
-       if !v.canSet {
-               panic(cannotSet)
+// Float returns v's underlying value, as a float64.
+// It panics if v's Kind is not Float32 or Float64
+func (v Value) Float() float64 {
+       k := v.kind()
+       switch k {
+       case Float32:
+               if v.flag&flagIndir != 0 {
+                       return float64(*(*float32)(v.val))
+               }
+               return float64(*(*float32)(unsafe.Pointer(&v.val)))
+       case Float64:
+               if v.flag&flagIndir != 0 {
+                       return *(*float64)(v.val)
+               }
+               return *(*float64)(unsafe.Pointer(&v.val))
        }
-       switch v.typ.Kind() {
-       default:
-               panic("reflect: invalid int kind")
+       panic(&ValueError{"reflect.Value.Float", k})
+}
+
+// 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 {
+       k := v.kind()
+       switch k {
+       case Array:
+               tt := (*arrayType)(unsafe.Pointer(v.typ))
+               if i < 0 || i > int(tt.len) {
+                       panic("reflect: array index out of range")
+               }
+               typ := toCommonType(tt.elem)
+               fl := v.flag & (flagRO | flagIndir | flagAddr) // bits same as overall array
+               fl |= flag(typ.Kind()) << flagKindShift
+               offset := uintptr(i) * typ.size
+
+               var val unsafe.Pointer
+               switch {
+               case fl&flagIndir != 0:
+                       // Indirect.  Just bump pointer.
+                       val = unsafe.Pointer(uintptr(v.val) + offset)
+               case bigEndian:
+                       // Direct.  Discard leading bytes.
+                       val = unsafe.Pointer(uintptr(v.val) << (offset * 8))
+               default:
+                       // Direct.  Discard leading bytes.
+                       val = unsafe.Pointer(uintptr(v.val) >> (offset * 8))
+               }
+               return Value{typ, val, fl}
+
+       case Slice:
+               // Element flag same as Elem of Ptr.
+               // Addressable, indirect, possibly read-only.
+               fl := flagAddr | flagIndir | v.flag&flagRO
+               s := (*SliceHeader)(v.val)
+               if i < 0 || i >= s.Len {
+                       panic("reflect: slice index out of range")
+               }
+               tt := (*sliceType)(unsafe.Pointer(v.typ))
+               typ := toCommonType(tt.elem)
+               fl |= flag(typ.Kind()) << flagKindShift
+               val := unsafe.Pointer(s.Data + uintptr(i)*typ.size)
+               return Value{typ, val, fl}
+       }
+       panic(&ValueError{"reflect.Value.Index", k})
+}
+
+// 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 {
+       k := v.kind()
+       var p unsafe.Pointer
+       if v.flag&flagIndir != 0 {
+               p = v.val
+       } else {
+               // The escape analysis is good enough that &v.val
+               // does not trigger a heap allocation.
+               p = unsafe.Pointer(&v.val)
+       }
+       switch k {
        case Int:
-               *(*int)(v.addr) = int(x)
+               return int64(*(*int)(p))
        case Int8:
-               *(*int8)(v.addr) = int8(x)
+               return int64(*(*int8)(p))
        case Int16:
-               *(*int16)(v.addr) = int16(x)
+               return int64(*(*int16)(p))
        case Int32:
-               *(*int32)(v.addr) = int32(x)
+               return int64(*(*int32)(p))
        case Int64:
-               *(*int64)(v.addr) = x
+               return int64(*(*int64)(p))
        }
+       panic(&ValueError{"reflect.Value.Int", k})
 }
 
-// Set sets v to the value x.
-func (v *IntValue) SetValue(x Value) { v.Set(x.(*IntValue).Get()) }
-
-// Overflow returns true if x cannot be represented by the type of v.
-func (v *IntValue) Overflow(x int64) bool {
-       bitSize := uint(v.typ.Bits())
-       trunc := (x << (64 - bitSize)) >> (64 - bitSize)
-       return x != trunc
+// CanInterface returns true if Interface can be used without panicking.
+func (v Value) CanInterface() bool {
+       if v.flag == 0 {
+               panic(&ValueError{"reflect.Value.CanInterface", Invalid})
+       }
+       return v.flag&(flagMethod|flagRO) == 0
 }
 
-// StringHeader is the runtime representation of a string.
-type StringHeader struct {
-       Data uintptr
-       Len  int
+// Interface returns v's current value as an interface{}.
+// It is equivalent to:
+//     var i interface{} = (v's underlying value)
+// If v is a method obtained by invoking Value.Method
+// (as opposed to Type.Method), Interface cannot return an
+// interface value, so it panics.
+// It also panics if the Value was obtained by accessing
+// unexported struct fields.
+func (v Value) Interface() (i interface{}) {
+       return valueInterface(v, true)
 }
 
-// StringValue represents a string value.
-type StringValue struct {
-       value "string"
-}
+func valueInterface(v Value, safe bool) interface{} {
+       if v.flag == 0 {
+               panic(&ValueError{"reflect.Value.Interface", 0})
+       }
+       if v.flag&flagMethod != 0 {
+               panic("reflect.Value.Interface: cannot create interface value for method with bound receiver")
+       }
 
-// Get returns the underlying string value.
-func (v *StringValue) Get() string { return *(*string)(v.addr) }
+       if safe && v.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")
+       }
 
-// Set sets v to the value x.
-func (v *StringValue) Set(x string) {
-       if !v.canSet {
-               panic(cannotSet)
+       k := v.kind()
+       if k == Interface {
+               // Special case: return the element inside the interface.
+               // Empty interface has one layout, all interfaces with
+               // methods have a second layout.
+               if v.NumMethod() == 0 {
+                       return *(*interface{})(v.val)
+               }
+               return *(*interface {
+                       M()
+               })(v.val)
+       }
+
+       // Non-interface value.
+       var eface emptyInterface
+       eface.typ = v.typ.runtimeType()
+       eface.word = v.iword()
+
+       if v.flag&flagIndir != 0 && v.kind() != Ptr && v.kind() != UnsafePointer {
+               // eface.word is a pointer to the actual data,
+               // which might be changed.  We need to return
+               // a pointer to unchanging data, so make a copy.
+               ptr := unsafe_New(v.typ)
+               memmove(ptr, unsafe.Pointer(eface.word), v.typ.size)
+               eface.word = iword(ptr)
+       }
+
+       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 {
+       v.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.
+       // Interface value is always bigger than a word; assume flagIndir.
+       return *(*[2]uintptr)(v.val)
+}
+
+// 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 {
+       k := v.kind()
+       switch k {
+       case Chan, Func, Map, Ptr:
+               if v.flag&flagMethod != 0 {
+                       panic("reflect: IsNil of method Value")
+               }
+               ptr := v.val
+               if v.flag&flagIndir != 0 {
+                       ptr = *(*unsafe.Pointer)(ptr)
+               }
+               return ptr == nil
+       case Interface, Slice:
+               // Both interface and slice are nil if first word is 0.
+               // Both are always bigger than a word; assume flagIndir.
+               return *(*unsafe.Pointer)(v.val) == nil
+       }
+       panic(&ValueError{"reflect.Value.IsNil", k})
+}
+
+// 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.flag != 0
+}
+
+// Kind returns v's Kind.
+// If v is the zero Value (IsValid returns false), Kind returns Invalid.
+func (v Value) Kind() Kind {
+       return v.kind()
+}
+
+// Len returns v's length.
+// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
+func (v Value) Len() int {
+       k := v.kind()
+       switch k {
+       case Array:
+               tt := (*arrayType)(unsafe.Pointer(v.typ))
+               return int(tt.len)
+       case Chan:
+               return int(chanlen(*(*iword)(v.iword())))
+       case Map:
+               return int(maplen(*(*iword)(v.iword())))
+       case Slice:
+               // Slice is bigger than a word; assume flagIndir.
+               return (*SliceHeader)(v.val).Len
+       case String:
+               // String is bigger than a word; assume flagIndir.
+               return (*StringHeader)(v.val).Len
+       }
+       panic(&ValueError{"reflect.Value.Len", k})
+}
+
+// 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 {
+       v.mustBe(Map)
+       tt := (*mapType)(unsafe.Pointer(v.typ))
+
+       // Do not require key 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.  This is consistent with the
+       // behavior for structs, which allow read but not write
+       // of unexported fields.
+       key = key.assignTo("reflect.Value.MapIndex", toCommonType(tt.key), nil)
+
+       word, ok := mapaccess(v.typ.runtimeType(), *(*iword)(v.iword()), key.iword())
+       if !ok {
+               return Value{}
+       }
+       typ := toCommonType(tt.elem)
+       fl := (v.flag | key.flag) & flagRO
+       if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
+               fl |= flagIndir
        }
-       *(*string)(v.addr) = x
+       fl |= flag(typ.Kind()) << flagKindShift
+       return Value{typ, unsafe.Pointer(word), fl}
 }
 
-// Set sets v to the value x.
-func (v *StringValue) SetValue(x Value) { v.Set(x.(*StringValue).Get()) }
-
-// UintValue represents a uint value.
-type UintValue struct {
-       value "uint"
-}
+// 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 {
+       v.mustBe(Map)
+       tt := (*mapType)(unsafe.Pointer(v.typ))
+       keyType := toCommonType(tt.key)
 
-// Get returns the underlying uuint value.
-func (v *UintValue) Get() uint64 {
-       switch v.typ.Kind() {
-       case Uint:
-               return uint64(*(*uint)(v.addr))
-       case Uint8:
-               return uint64(*(*uint8)(v.addr))
-       case Uint16:
-               return uint64(*(*uint16)(v.addr))
-       case Uint32:
-               return uint64(*(*uint32)(v.addr))
-       case Uint64:
-               return *(*uint64)(v.addr)
-       case Uintptr:
-               return uint64(*(*uintptr)(v.addr))
+       fl := v.flag & flagRO
+       fl |= flag(keyType.Kind()) << flagKindShift
+       if keyType.Kind() != Ptr && keyType.Kind() != UnsafePointer {
+               fl |= flagIndir
        }
-       panic("reflect: invalid uint kind")
-}
 
-// Set sets v to the value x.
-func (v *UintValue) Set(x uint64) {
-       if !v.canSet {
-               panic(cannotSet)
+       m := *(*iword)(v.iword())
+       mlen := int32(0)
+       if m != nil {
+               mlen = maplen(m)
        }
-       switch v.typ.Kind() {
-       default:
-               panic("reflect: invalid uint kind")
-       case Uint:
-               *(*uint)(v.addr) = uint(x)
-       case Uint8:
-               *(*uint8)(v.addr) = uint8(x)
-       case Uint16:
-               *(*uint16)(v.addr) = uint16(x)
-       case Uint32:
-               *(*uint32)(v.addr) = uint32(x)
-       case Uint64:
-               *(*uint64)(v.addr) = x
-       case Uintptr:
-               *(*uintptr)(v.addr) = uintptr(x)
+       it := mapiterinit(v.typ.runtimeType(), m)
+       a := make([]Value, mlen)
+       var i int
+       for i = 0; i < len(a); i++ {
+               keyWord, ok := mapiterkey(it)
+               if !ok {
+                       break
+               }
+               a[i] = Value{keyType, unsafe.Pointer(keyWord), fl}
+               mapiternext(it)
        }
+       return a[:i]
 }
 
-// Overflow returns true if x cannot be represented by the type of v.
-func (v *UintValue) Overflow(x uint64) bool {
-       bitSize := uint(v.typ.Bits())
-       trunc := (x << (64 - bitSize)) >> (64 - bitSize)
-       return x != trunc
+// 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 {
+       if v.typ == nil {
+               panic(&ValueError{"reflect.Value.Method", Invalid})
+       }
+       if v.flag&flagMethod != 0 || i < 0 || i >= v.typ.NumMethod() {
+               panic("reflect: Method index out of range")
+       }
+       fl := v.flag & (flagRO | flagAddr | flagIndir)
+       fl |= flag(Func) << flagKindShift
+       fl |= flag(i)<<flagMethodShift | flagMethod
+       return Value{v.typ, v.val, fl}
 }
 
-// Set sets v to the value x.
-func (v *UintValue) SetValue(x Value) { v.Set(x.(*UintValue).Get()) }
-
-// UnsafePointerValue represents an unsafe.Pointer value.
-type UnsafePointerValue struct {
-       value "unsafe.Pointer"
+// NumMethod returns the number of methods in the value's method set.
+func (v Value) NumMethod() int {
+       if v.typ == nil {
+               panic(&ValueError{"reflect.Value.NumMethod", Invalid})
+       }
+       if v.flag&flagMethod != 0 {
+               return 0
+       }
+       return v.typ.NumMethod()
 }
 
-// Get returns the underlying uintptr value.
-// Get returns uintptr, not unsafe.Pointer, so that
-// programs that do not import "unsafe" cannot
-// obtain a value of unsafe.Pointer type from "reflect".
-func (v *UnsafePointerValue) Get() uintptr { return uintptr(*(*unsafe.Pointer)(v.addr)) }
-
-// Set sets v to the value x.
-func (v *UnsafePointerValue) Set(x unsafe.Pointer) {
-       if !v.canSet {
-               panic(cannotSet)
+// MethodByName returns a function value corresponding to the method
+// of v with the given name.
+// The arguments to a Call on the returned function should not include
+// a receiver; the returned function will always use v as the receiver.
+// It returns the zero Value if no method was found.
+func (v Value) MethodByName(name string) Value {
+       if v.typ == nil {
+               panic(&ValueError{"reflect.Value.MethodByName", Invalid})
        }
-       *(*unsafe.Pointer)(v.addr) = x
+       if v.flag&flagMethod != 0 {
+               return Value{}
+       }
+       m, ok := v.typ.MethodByName(name)
+       if !ok {
+               return Value{}
+       }
+       return v.Method(m.Index)
 }
 
-// Set sets v to the value x.
-func (v *UnsafePointerValue) SetValue(x Value) {
-       v.Set(unsafe.Pointer(x.(*UnsafePointerValue).Get()))
+// NumField returns the number of fields in the struct v.
+// It panics if v's Kind is not Struct.
+func (v Value) NumField() int {
+       v.mustBe(Struct)
+       tt := (*structType)(unsafe.Pointer(v.typ))
+       return len(tt.fields)
 }
 
-func typesMustMatch(t1, t2 Type) {
-       if t1 != t2 {
-               panic("type mismatch: " + t1.String() + " != " + t2.String())
+// 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 {
+       k := v.kind()
+       switch k {
+       case Complex64:
+               return overflowFloat32(real(x)) || overflowFloat32(imag(x))
+       case Complex128:
+               return false
        }
+       panic(&ValueError{"reflect.Value.OverflowComplex", k})
 }
 
-/*
- * array
- */
-
-// ArrayOrSliceValue is the common interface
-// implemented by both ArrayValue and SliceValue.
-type ArrayOrSliceValue interface {
-       Value
-       Len() int
-       Cap() int
-       Elem(i int) Value
-       addr() addr
+// 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 {
+       k := v.kind()
+       switch k {
+       case Float32:
+               return overflowFloat32(x)
+       case Float64:
+               return false
+       }
+       panic(&ValueError{"reflect.Value.OverflowFloat", k})
 }
 
-// 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 *SliceValue, extra int) (*SliceValue, int, int) {
-       i0 := s.Len()
-       i1 := i0 + extra
-       if i1 < i0 {
-               panic("append: slice overflow")
-       }
-       m := s.Cap()
-       if i1 <= m {
-               return s.Slice(0, i1), i0, i1
+func overflowFloat32(x float64) bool {
+       if x < 0 {
+               x = -x
        }
-       if m == 0 {
-               m = extra
-       } else {
-               for m < i1 {
-                       if i0 < 1024 {
-                               m += m
-                       } else {
-                               m += m / 4
-                       }
+       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 {
+       k := v.kind()
+       switch k {
+       case Int, Int8, Int16, Int32, Int64:
+               bitSize := v.typ.size * 8
+               trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+               return x != trunc
+       }
+       panic(&ValueError{"reflect.Value.OverflowInt", k})
+}
+
+// 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 {
+       k := v.kind()
+       switch k {
+       case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
+               bitSize := v.typ.size * 8
+               trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+               return x != trunc
+       }
+       panic(&ValueError{"reflect.Value.OverflowUint", k})
+}
+
+// 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 {
+       k := v.kind()
+       switch k {
+       case Chan, Func, Map, Ptr, UnsafePointer:
+               if k == Func && v.flag&flagMethod != 0 {
+                       panic("reflect.Value.Pointer of method Value")
+               }
+               p := v.val
+               if v.flag&flagIndir != 0 {
+                       p = *(*unsafe.Pointer)(p)
                }
+               return uintptr(p)
+       case Slice:
+               return (*SliceHeader)(v.val).Data
        }
-       t := MakeSlice(s.Type().(*SliceType), i1, m)
-       Copy(t, s)
-       return t, i0, i1
+       panic(&ValueError{"reflect.Value.Pointer", k})
 }
 
-// Append appends the values x to a slice s and returns the resulting slice.
-// Each x must have the same type as s' element type.
-func Append(s *SliceValue, x ...Value) *SliceValue {
-       s, i0, i1 := grow(s, len(x))
-       for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
-               s.Elem(i).SetValue(x[j])
+// 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) {
+       v.mustBe(Chan)
+       v.mustBeExported()
+       return v.recv(false)
+}
+
+// internal recv, possibly non-blocking (nb).
+// v is known to be a channel.
+func (v Value) recv(nb bool) (val Value, ok bool) {
+       tt := (*chanType)(unsafe.Pointer(v.typ))
+       if ChanDir(tt.dir)&RecvDir == 0 {
+               panic("recv on send-only channel")
        }
-       return s
+       word, selected, ok := chanrecv(v.typ.runtimeType(), *(*iword)(v.iword()), nb)
+       if selected {
+               typ := toCommonType(tt.elem)
+               fl := flag(typ.Kind()) << flagKindShift
+               if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
+                       fl |= flagIndir
+               }
+               val = Value{typ, unsafe.Pointer(word), fl}
+       }
+       return
 }
 
-// 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 *SliceValue) *SliceValue {
-       s, i0, i1 := grow(s, t.Len())
-       Copy(s.Slice(i0, i1), t)
-       return s
+// 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) {
+       v.mustBe(Chan)
+       v.mustBeExported()
+       v.send(x, false)
+}
+
+// internal send, possibly non-blocking.
+// v is known to be a channel.
+func (v Value) send(x Value, nb bool) (selected bool) {
+       tt := (*chanType)(unsafe.Pointer(v.typ))
+       if ChanDir(tt.dir)&SendDir == 0 {
+               panic("send on recv-only channel")
+       }
+       x.mustBeExported()
+       x = x.assignTo("reflect.Value.Send", toCommonType(tt.elem), nil)
+       return chansend(v.typ.runtimeType(), *(*iword)(v.iword()), x.iword(), nb)
 }
 
-// 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.
-// The arrays dst and src must have the same element type.
-func Copy(dst, src ArrayOrSliceValue) int {
-       // TODO: This will have to move into the runtime
-       // once the real gc goes in.
-       de := dst.Type().(ArrayOrSliceType).Elem()
-       se := src.Type().(ArrayOrSliceType).Elem()
-       typesMustMatch(de, se)
-       n := dst.Len()
-       if xn := src.Len(); n > xn {
-               n = xn
+// 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) {
+       v.mustBeAssignable()
+       x.mustBeExported() // do not let unexported x leak
+       var target *interface{}
+       if v.kind() == Interface {
+               target = (*interface{})(v.val)
+       }
+       x = x.assignTo("reflect.Set", v.typ, target)
+       if x.flag&flagIndir != 0 {
+               memmove(v.val, x.val, v.typ.size)
+       } else {
+               storeIword(v.val, iword(x.val), v.typ.size)
        }
-       memmove(dst.addr(), src.addr(), uintptr(n)*de.Size())
-       return n
 }
 
-// An ArrayValue represents an array.
-type ArrayValue struct {
-       value "array"
+// 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) {
+       v.mustBeAssignable()
+       v.mustBe(Bool)
+       *(*bool)(v.val) = x
 }
 
-// Len returns the length of the array.
-func (v *ArrayValue) Len() int { return v.typ.(*ArrayType).Len() }
-
-// Cap returns the capacity of the array (equal to Len()).
-func (v *ArrayValue) Cap() int { return v.typ.(*ArrayType).Len() }
-
-// addr returns the base address of the data in the array.
-func (v *ArrayValue) addr() addr { return v.value.addr }
-
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *ArrayValue) Set(x *ArrayValue) {
-       if !v.canSet {
-               panic(cannotSet)
+// SetBytes sets v's underlying value.
+// It panics if v's underlying value is not a slice of bytes.
+func (v Value) SetBytes(x []byte) {
+       v.mustBeAssignable()
+       v.mustBe(Slice)
+       if v.typ.Elem().Kind() != Uint8 {
+               panic("reflect.Value.SetBytes of non-byte slice")
        }
-       typesMustMatch(v.typ, x.typ)
-       Copy(v, x)
+       *(*[]byte)(v.val) = x
 }
 
-// Set sets v to the value x.
-func (v *ArrayValue) SetValue(x Value) { v.Set(x.(*ArrayValue)) }
-
-// Elem returns the i'th element of v.
-func (v *ArrayValue) Elem(i int) Value {
-       typ := v.typ.(*ArrayType).Elem()
-       n := v.Len()
-       if i < 0 || i >= n {
-               panic("array index out of bounds")
+// 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) {
+       v.mustBeAssignable()
+       switch k := v.kind(); k {
+       default:
+               panic(&ValueError{"reflect.Value.SetComplex", k})
+       case Complex64:
+               *(*complex64)(v.val) = complex64(x)
+       case Complex128:
+               *(*complex128)(v.val) = x
        }
-       p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size())
-       return newValue(typ, p, v.canSet)
 }
 
-/*
- * slice
- */
-
-// runtime representation of slice
-type SliceHeader struct {
-       Data uintptr
-       Len  int
-       Cap  int
+// 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) {
+       v.mustBeAssignable()
+       switch k := v.kind(); k {
+       default:
+               panic(&ValueError{"reflect.Value.SetFloat", k})
+       case Float32:
+               *(*float32)(v.val) = float32(x)
+       case Float64:
+               *(*float64)(v.val) = x
+       }
 }
 
-// A SliceValue represents a slice.
-type SliceValue struct {
-       value "slice"
+// 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) {
+       v.mustBeAssignable()
+       switch k := v.kind(); k {
+       default:
+               panic(&ValueError{"reflect.Value.SetInt", k})
+       case Int:
+               *(*int)(v.val) = int(x)
+       case Int8:
+               *(*int8)(v.val) = int8(x)
+       case Int16:
+               *(*int16)(v.val) = int16(x)
+       case Int32:
+               *(*int32)(v.val) = int32(x)
+       case Int64:
+               *(*int64)(v.val) = x
+       }
 }
 
-func (v *SliceValue) slice() *SliceHeader { return (*SliceHeader)(v.value.addr) }
-
-// IsNil returns whether v is a nil slice.
-func (v *SliceValue) IsNil() bool { return v.slice().Data == 0 }
-
-// Len returns the length of the slice.
-func (v *SliceValue) Len() int { return int(v.slice().Len) }
-
-// Cap returns the capacity of the slice.
-func (v *SliceValue) Cap() int { return int(v.slice().Cap) }
-
-// addr returns the base address of the data in the slice.
-func (v *SliceValue) addr() addr { return addr(v.slice().Data) }
-
-// SetLen changes the length of v.
-// The new length n must be between 0 and the capacity, inclusive.
-func (v *SliceValue) SetLen(n int) {
-       s := v.slice()
+// SetLen sets v's length to n.
+// It panics if v's Kind is not Slice or if n is negative or
+// greater than the capacity of the slice.
+func (v Value) SetLen(n int) {
+       v.mustBeAssignable()
+       v.mustBe(Slice)
+       s := (*SliceHeader)(v.val)
        if n < 0 || n > int(s.Cap) {
                panic("reflect: slice length out of range in SetLen")
        }
        s.Len = n
 }
 
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *SliceValue) Set(x *SliceValue) {
-       if !v.canSet {
-               panic(cannotSet)
+// 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) {
+       v.mustBe(Map)
+       v.mustBeExported()
+       key.mustBeExported()
+       tt := (*mapType)(unsafe.Pointer(v.typ))
+       key = key.assignTo("reflect.Value.SetMapIndex", toCommonType(tt.key), nil)
+       if val.typ != nil {
+               val.mustBeExported()
+               val = val.assignTo("reflect.Value.SetMapIndex", toCommonType(tt.elem), nil)
+       }
+       mapassign(v.typ.runtimeType(), *(*iword)(v.iword()), key.iword(), val.iword(), val.typ != nil)
+}
+
+// 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) {
+       v.mustBeAssignable()
+       switch k := v.kind(); k {
+       default:
+               panic(&ValueError{"reflect.Value.SetUint", k})
+       case Uint:
+               *(*uint)(v.val) = uint(x)
+       case Uint8:
+               *(*uint8)(v.val) = uint8(x)
+       case Uint16:
+               *(*uint16)(v.val) = uint16(x)
+       case Uint32:
+               *(*uint32)(v.val) = uint32(x)
+       case Uint64:
+               *(*uint64)(v.val) = x
+       case Uintptr:
+               *(*uintptr)(v.val) = uintptr(x)
        }
-       typesMustMatch(v.typ, x.typ)
-       *v.slice() = *x.slice()
 }
 
-// Set sets v to the value x.
-func (v *SliceValue) SetValue(x Value) { v.Set(x.(*SliceValue)) }
-
-// Get returns the uintptr address of the v.Cap()'th element.  This gives
-// the same result for all slices of the same array.
-// It is mainly useful for printing.
-func (v *SliceValue) Get() uintptr {
-       typ := v.typ.(*SliceType)
-       return uintptr(v.addr()) + uintptr(v.Cap())*typ.Elem().Size()
+// 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) {
+       v.mustBeAssignable()
+       v.mustBe(UnsafePointer)
+       *(*unsafe.Pointer)(v.val) = x
 }
 
-// Slice returns a sub-slice of the slice v.
-func (v *SliceValue) Slice(beg, end int) *SliceValue {
-       cap := v.Cap()
-       if beg < 0 || end < beg || end > cap {
-               panic("slice index out of bounds")
-       }
-       typ := v.typ.(*SliceType)
-       s := new(SliceHeader)
-       s.Data = uintptr(v.addr()) + uintptr(beg)*typ.Elem().Size()
-       s.Len = end - beg
-       s.Cap = cap - beg
-       return newValue(typ, addr(s), v.canSet).(*SliceValue)
+// 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) {
+       v.mustBeAssignable()
+       v.mustBe(String)
+       *(*string)(v.val) = x
 }
 
-// Elem returns the i'th element of v.
-func (v *SliceValue) Elem(i int) Value {
-       typ := v.typ.(*SliceType).Elem()
-       n := v.Len()
-       if i < 0 || i >= n {
-               panic("reflect: slice index out of range")
-       }
-       p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size())
-       return newValue(typ, p, v.canSet)
-}
+// 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 {
+       var (
+               cap  int
+               typ  *sliceType
+               base unsafe.Pointer
+       )
+       switch k := v.kind(); k {
+       default:
+               panic(&ValueError{"reflect.Value.Slice", k})
+       case Array:
+               if v.flag&flagAddr == 0 {
+                       panic("reflect.Value.Slice: slice of unaddressable array")
+               }
+               tt := (*arrayType)(unsafe.Pointer(v.typ))
+               cap = int(tt.len)
+               typ = (*sliceType)(unsafe.Pointer(toCommonType(tt.slice)))
+               base = v.val
+       case Slice:
+               typ = (*sliceType)(unsafe.Pointer(v.typ))
+               s := (*SliceHeader)(v.val)
+               base = unsafe.Pointer(s.Data)
+               cap = s.Cap
 
-// MakeSlice creates a new zero-initialized slice value
-// for the specified slice type, length, and capacity.
-func MakeSlice(typ *SliceType, len, cap int) *SliceValue {
-       s := &SliceHeader{
-               Data: uintptr(unsafe.NewArray(typ.Elem(), cap)),
-               Len:  len,
-               Cap:  cap,
        }
-       return newValue(typ, addr(s), true).(*SliceValue)
-}
-
-/*
- * chan
- */
-
-// A ChanValue represents a chan.
-type ChanValue struct {
-       value "chan"
-}
-
-// IsNil returns whether v is a nil channel.
-func (v *ChanValue) IsNil() bool { return *(*uintptr)(v.addr) == 0 }
-
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *ChanValue) Set(x *ChanValue) {
-       if !v.canSet {
-               panic(cannotSet)
+       if beg < 0 || end < beg || end > cap {
+               panic("reflect.Value.Slice: slice index out of bounds")
        }
-       typesMustMatch(v.typ, x.typ)
-       *(*uintptr)(v.addr) = *(*uintptr)(x.addr)
-}
 
-// Set sets v to the value x.
-func (v *ChanValue) SetValue(x Value) { v.Set(x.(*ChanValue)) }
-
-// Get returns the uintptr value of v.
-// It is mainly useful for printing.
-func (v *ChanValue) Get() uintptr { return *(*uintptr)(v.addr) }
-
-// implemented in ../pkg/runtime/reflect.cgo
-func makechan(typ *runtime.ChanType, size uint32) (ch *byte)
-func chansend(ch, val *byte, pres *bool)
-func chanrecv(ch, val *byte, pres *bool)
-func chanclosed(ch *byte) bool
-func chanclose(ch *byte)
-func chanlen(ch *byte) int32
-func chancap(ch *byte) int32
-
-// Closed returns the result of closed(c) on the underlying channel.
-func (v *ChanValue) Closed() bool {
-       ch := *(**byte)(v.addr)
-       return chanclosed(ch)
-}
+       // Declare slice so that gc can see the base pointer in it.
+       var x []byte
 
-// Close closes the channel.
-func (v *ChanValue) Close() {
-       ch := *(**byte)(v.addr)
-       chanclose(ch)
-}
-
-func (v *ChanValue) Len() int {
-       ch := *(**byte)(v.addr)
-       return int(chanlen(ch))
-}
+       // Reinterpret as *SliceHeader to edit.
+       s := (*SliceHeader)(unsafe.Pointer(&x))
+       s.Data = uintptr(base) + uintptr(beg)*toCommonType(typ.elem).Size()
+       s.Len = end - beg
+       s.Cap = cap - beg
 
-func (v *ChanValue) Cap() int {
-       ch := *(**byte)(v.addr)
-       return int(chancap(ch))
+       fl := v.flag&flagRO | flagIndir | flag(Slice)<<flagKindShift
+       return Value{typ.common(), unsafe.Pointer(&x), fl}
 }
 
-// internal send; non-blocking if b != nil
-func (v *ChanValue) send(x Value, b *bool) {
-       t := v.Type().(*ChanType)
-       if t.Dir()&SendDir == 0 {
-               panic("send on recv-only channel")
+// 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 {
+       switch k := v.kind(); k {
+       case Invalid:
+               return "<invalid Value>"
+       case String:
+               return *(*string)(v.val)
        }
-       typesMustMatch(t.Elem(), x.Type())
-       ch := *(**byte)(v.addr)
-       chansend(ch, (*byte)(x.getAddr()), b)
+       // If you call String on a reflect.Value of other type, it's better to
+       // print something than to panic. Useful in debugging.
+       return "<" + v.typ.String() + " Value>"
 }
 
-// internal recv; non-blocking if b != nil
-func (v *ChanValue) recv(b *bool) Value {
-       t := v.Type().(*ChanType)
-       if t.Dir()&RecvDir == 0 {
-               panic("recv on send-only channel")
-       }
-       ch := *(**byte)(v.addr)
-       x := MakeZero(t.Elem())
-       chanrecv(ch, (*byte)(x.getAddr()), b)
-       return x
-}
-
-// Send sends x on the channel v.
-func (v *ChanValue) Send(x Value) { v.send(x, nil) }
-
-// Recv receives and returns a value from the channel v.
-func (v *ChanValue) Recv() Value { return v.recv(nil) }
-
-// TrySend attempts to sends x on the channel v but will not block.
+// 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) {
+       v.mustBe(Chan)
+       v.mustBeExported()
+       return v.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.
-func (v *ChanValue) TrySend(x Value) bool {
-       var ok bool
-       v.send(x, &ok)
-       return ok
+// As in Go, x's value must be assignable to the channel's element type.
+func (v Value) TrySend(x Value) bool {
+       v.mustBe(Chan)
+       v.mustBeExported()
+       return v.send(x, true)
+}
+
+// Type returns v's type.
+func (v Value) Type() Type {
+       f := v.flag
+       if f == 0 {
+               panic(&ValueError{"reflect.Value.Type", Invalid})
+       }
+       if f&flagMethod == 0 {
+               // Easy case
+               return v.typ.toType()
+       }
+
+       // Method value.
+       // v.typ describes the receiver, not the method type.
+       i := int(v.flag) >> flagMethodShift
+       if v.typ.Kind() == Interface {
+               // Method on interface.
+               tt := (*interfaceType)(unsafe.Pointer(v.typ))
+               if i < 0 || i >= len(tt.methods) {
+                       panic("reflect: broken Value")
+               }
+               m := &tt.methods[i]
+               return toCommonType(m.typ).toType()
+       }
+       // Method on concrete type.
+       ut := v.typ.uncommon()
+       if ut == nil || i < 0 || i >= len(ut.methods) {
+               panic("reflect: broken Value")
+       }
+       m := &ut.methods[i]
+       return toCommonType(m.mtyp).toType()
 }
 
-// TryRecv attempts to receive a value from the channel v but will not block.
-// It returns the value if one is received, nil otherwise.
-func (v *ChanValue) TryRecv() Value {
-       var ok bool
-       x := v.recv(&ok)
-       if !ok {
-               return nil
+// 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 {
+       k := v.kind()
+       var p unsafe.Pointer
+       if v.flag&flagIndir != 0 {
+               p = v.val
+       } else {
+               // The escape analysis is good enough that &v.val
+               // does not trigger a heap allocation.
+               p = unsafe.Pointer(&v.val)
+       }
+       switch k {
+       case Uint:
+               return uint64(*(*uint)(p))
+       case Uint8:
+               return uint64(*(*uint8)(p))
+       case Uint16:
+               return uint64(*(*uint16)(p))
+       case Uint32:
+               return uint64(*(*uint32)(p))
+       case Uint64:
+               return uint64(*(*uint64)(p))
+       case Uintptr:
+               return uint64(*(*uintptr)(p))
        }
-       return x
+       panic(&ValueError{"reflect.Value.Uint", k})
 }
 
-// MakeChan creates a new channel with the specified type and buffer size.
-func MakeChan(typ *ChanType, buffer int) *ChanValue {
-       if buffer < 0 {
-               panic("MakeChan: negative buffer size")
+// 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 {
+       if v.typ == nil {
+               panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
        }
-       if typ.Dir() != BothDir {
-               panic("MakeChan: unidirectional channel type")
+       if v.flag&flagAddr == 0 {
+               panic("reflect.Value.UnsafeAddr of unaddressable value")
        }
-       v := MakeZero(typ).(*ChanValue)
-       *(**byte)(v.addr) = makechan((*runtime.ChanType)(unsafe.Pointer(typ)), uint32(buffer))
-       return v
+       return uintptr(v.val)
 }
 
-/*
- * func
- */
-
-// A FuncValue represents a function value.
-type FuncValue struct {
-       value       "func"
-       first       *value
-       isInterface bool
+// StringHeader is the runtime representation of a string.
+// It cannot be used safely or portably.
+type StringHeader struct {
+       Data uintptr
+       Len  int
 }
 
-// IsNil returns whether v is a nil function.
-func (v *FuncValue) IsNil() bool { return *(*uintptr)(v.addr) == 0 }
-
-// Get returns the uintptr value of v.
-// It is mainly useful for printing.
-func (v *FuncValue) Get() uintptr { return *(*uintptr)(v.addr) }
-
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *FuncValue) Set(x *FuncValue) {
-       if !v.canSet {
-               panic(cannotSet)
-       }
-       typesMustMatch(v.typ, x.typ)
-       *(*uintptr)(v.addr) = *(*uintptr)(x.addr)
+// SliceHeader is the runtime representation of a slice.
+// It cannot be used safely or portably.
+type SliceHeader struct {
+       Data uintptr
+       Len  int
+       Cap  int
 }
 
-// Set sets v to the value x.
-func (v *FuncValue) SetValue(x Value) { v.Set(x.(*FuncValue)) }
-
-// Method returns a FuncValue corresponding to v's i'th method.
-// The arguments to a Call on the returned FuncValue
-// should not include a receiver; the FuncValue will use v
-// as the receiver.
-func (v *value) Method(i int) *FuncValue {
-       t := v.Type().uncommon()
-       if t == nil || i < 0 || i >= len(t.methods) {
-               return nil
+func typesMustMatch(what string, t1, t2 Type) {
+       if t1 != t2 {
+               panic(what + ": " + t1.String() + " != " + t2.String())
        }
-       p := &t.methods[i]
-       fn := p.tfn
-       fv := &FuncValue{value: value{runtimeToType(p.typ), addr(&fn), true}, first: v, isInterface: false}
-       return fv
 }
 
-// implemented in ../pkg/runtime/*/asm.s
-func call(typ *FuncType, fnaddr *byte, isInterface bool, params *addr, results *addr)
-
-// Call calls the function fv with input parameters in.
-// It returns the function's output parameters as Values.
-func (fv *FuncValue) Call(in []Value) []Value {
-       t := fv.Type().(*FuncType)
-       nin := len(in)
-       if fv.first != nil && !fv.isInterface {
-               nin++
-       }
-       if nin != t.NumIn() {
-               panic("FuncValue: wrong argument count")
+// 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")
        }
-       if fv.first != nil && fv.isInterface {
-               nin++
+       m := s.Cap()
+       if i1 <= m {
+               return s.Slice(0, i1), i0, i1
        }
-       nout := t.NumOut()
-
-       params := make([]addr, nin)
-       delta := 0
-       off := 0
-       if v := fv.first; v != nil {
-               // Hard-wired first argument.
-               if fv.isInterface {
-                       // v is a single uninterpreted word
-                       params[0] = v.getAddr()
-               } else {
-                       // v is a real value
-                       tv := v.Type()
-
-                       // This is a method, so we need to always pass
-                       // a pointer.
-                       vAddr := v.getAddr()
-                       if ptv, ok := tv.(*PtrType); ok {
-                               typesMustMatch(t.In(0), tv)
+       if m == 0 {
+               m = extra
+       } else {
+               for m < i1 {
+                       if i0 < 1024 {
+                               m += m
                        } else {
-                               p := addr(new(addr))
-                               *(*addr)(p) = vAddr
-                               vAddr = p
-                               typesMustMatch(t.In(0).(*PtrType).Elem(), tv)
-                       }
-
-                       params[0] = vAddr
-                       delta = 1
-               }
-               off = 1
-       }
-       for i, v := range in {
-               tv := v.Type()
-               tf := t.In(i + delta)
-
-               // If this is really a method, and we are explicitly
-               // passing the object, then we need to pass the address
-               // of the object instead.  Unfortunately, we don't
-               // have any way to know that this is a method, so we just
-               // check the type.  FIXME: This is ugly.
-               vAddr := v.getAddr()
-               if i == 0 && tf != tv {
-                       if ptf, ok := tf.(*PtrType); ok {
-                               p := addr(new(addr))
-                               *(*addr)(p) = vAddr
-                               vAddr = p
-                               tf = ptf.Elem()
+                               m += m / 4
                        }
                }
-
-               typesMustMatch(tf, tv)
-               params[i+off] = vAddr
-       }
-
-       ret := make([]Value, nout)
-       results := make([]addr, nout)
-       for i := 0; i < nout; i++ {
-               tv := t.Out(i)
-               v := MakeZero(tv)
-               results[i] = v.getAddr()
-               ret[i] = v
        }
-
-       call(t, *(**byte)(fv.addr), fv.isInterface, &params[0], &results[0])
-
-       return ret
+       t := MakeSlice(s.Type(), i1, m)
+       Copy(t, s)
+       return t, i0, i1
 }
 
-/*
- * interface
- */
-
-// An InterfaceValue represents an interface value.
-type InterfaceValue struct {
-       value "interface"
+// 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.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
 }
 
-// IsNil returns whether v is a nil interface value.
-func (v *InterfaceValue) IsNil() bool { return v.Interface() == nil }
-
-// No single uinptr Get because v.Interface() is available.
-
-// Get returns the two words that represent an interface in the runtime.
-// Those words are useful only when playing unsafe games.
-func (v *InterfaceValue) Get() [2]uintptr {
-       return *(*[2]uintptr)(v.addr)
+// 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.mustBe(Slice)
+       t.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
 }
 
-// Elem returns the concrete value stored in the interface value v.
-func (v *InterfaceValue) Elem() Value { return NewValue(v.Interface()) }
-
-// ../runtime/reflect.cgo
-func setiface(typ *InterfaceType, x *interface{}, addr addr)
-
-// Set assigns x to v.
-func (v *InterfaceValue) Set(x Value) {
-       var i interface{}
-       if x != nil {
-               i = x.Interface()
-       }
-       if !v.canSet {
-               panic(cannotSet)
+// 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 {
+       dk := dst.kind()
+       if dk != Array && dk != Slice {
+               panic(&ValueError{"reflect.Copy", dk})
        }
-       // Two different representations; see comment in Get.
-       // Empty interface is easy.
-       t := v.typ.(*InterfaceType)
-       if t.NumMethod() == 0 {
-               *(*interface{})(v.addr) = i
-               return
+       if dk == Array {
+               dst.mustBeAssignable()
        }
+       dst.mustBeExported()
 
-       // Non-empty interface requires a runtime check.
-       setiface(t, &i, v.addr)
-}
+       sk := src.kind()
+       if sk != Array && sk != Slice {
+               panic(&ValueError{"reflect.Copy", sk})
+       }
+       src.mustBeExported()
 
-// Set sets v to the value x.
-func (v *InterfaceValue) SetValue(x Value) { v.Set(x) }
+       de := dst.typ.Elem()
+       se := src.typ.Elem()
+       typesMustMatch("reflect.Copy", de, se)
 
-// Method returns a FuncValue corresponding to v's i'th method.
-// The arguments to a Call on the returned FuncValue
-// should not include a receiver; the FuncValue will use v
-// as the receiver.
-func (v *InterfaceValue) Method(i int) *FuncValue {
-       t := v.Type().(*InterfaceType)
-       if t == nil || i < 0 || i >= len(t.methods) {
-               return nil
+       n := dst.Len()
+       if sn := src.Len(); n > sn {
+               n = sn
        }
-       p := &t.methods[i]
 
-       // Interface is two words: itable, data.
-       tab := *(**[10000]addr)(v.addr)
-       data := &value{Typeof((*byte)(nil)), addr(uintptr(v.addr) + ptrSize), true}
+       // If sk is an in-line array, cannot take its address.
+       // Instead, copy element by element.
+       if src.flag&flagIndir == 0 {
+               for i := 0; i < n; i++ {
+                       dst.Index(i).Set(src.Index(i))
+               }
+               return n
+       }
 
-       fn := tab[i+1]
-       fv := &FuncValue{value: value{runtimeToType(p.typ), addr(&fn), true}, first: data, isInterface: true}
-       return fv
+       // Copy via memmove.
+       var da, sa unsafe.Pointer
+       if dk == Array {
+               da = dst.val
+       } else {
+               da = unsafe.Pointer((*SliceHeader)(dst.val).Data)
+       }
+       if sk == Array {
+               sa = src.val
+       } else {
+               sa = unsafe.Pointer((*SliceHeader)(src.val).Data)
+       }
+       memmove(da, sa, uintptr(n)*de.Size())
+       return n
 }
 
 /*
- * map
+ * constructors
  */
 
-// A MapValue represents a map value.
-type MapValue struct {
-       value "map"
-}
-
-// IsNil returns whether v is a nil map value.
-func (v *MapValue) IsNil() bool { return *(*uintptr)(v.addr) == 0 }
+// implemented in package runtime
+func unsafe_New(Type) unsafe.Pointer
+func unsafe_NewArray(Type, int) unsafe.Pointer
 
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *MapValue) Set(x *MapValue) {
-       if !v.canSet {
-               panic(cannotSet)
-       }
-       if x == nil {
-               *(**uintptr)(v.addr) = nil
-               return
+// 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")
        }
-       typesMustMatch(v.typ, x.typ)
-       *(*uintptr)(v.addr) = *(*uintptr)(x.addr)
-}
-
-// Set sets v to the value x.
-func (v *MapValue) SetValue(x Value) {
-       if x == nil {
-               v.Set(nil)
-               return
+       if len < 0 {
+               panic("reflect.MakeSlice: negative len")
        }
-       v.Set(x.(*MapValue))
-}
-
-// Get returns the uintptr value of v.
-// It is mainly useful for printing.
-func (v *MapValue) Get() uintptr { return *(*uintptr)(v.addr) }
-
-// implemented in ../pkg/runtime/reflect.cgo
-func mapaccess(m, key, val *byte) bool
-func mapassign(m, key, val *byte)
-func maplen(m *byte) int32
-func mapiterinit(m *byte) *byte
-func mapiternext(it *byte)
-func mapiterkey(it *byte, key *byte) bool
-func makemap(t *runtime.MapType) *byte
-
-// Elem returns the value associated with key in the map v.
-// It returns nil if key is not found in the map.
-func (v *MapValue) Elem(key Value) Value {
-       t := v.Type().(*MapType)
-       typesMustMatch(t.Key(), key.Type())
-       m := *(**byte)(v.addr)
-       if m == nil {
-               return nil
-       }
-       newval := MakeZero(t.Elem())
-       if !mapaccess(m, (*byte)(key.getAddr()), (*byte)(newval.getAddr())) {
-               return nil
-       }
-       return newval
-}
-
-// SetElem sets the value associated with key in the map v to val.
-// If val is nil, Put deletes the key from map.
-func (v *MapValue) SetElem(key, val Value) {
-       t := v.Type().(*MapType)
-       typesMustMatch(t.Key(), key.Type())
-       var vaddr *byte
-       if val != nil {
-               typesMustMatch(t.Elem(), val.Type())
-               vaddr = (*byte)(val.getAddr())
-       }
-       m := *(**byte)(v.addr)
-       mapassign(m, (*byte)(key.getAddr()), vaddr)
-}
-
-// Len returns the number of keys in the map v.
-func (v *MapValue) Len() int {
-       m := *(**byte)(v.addr)
-       if m == nil {
-               return 0
-       }
-       return int(maplen(m))
-}
-
-// Keys returns a slice containing all the keys present in the map,
-// in unspecified order.
-func (v *MapValue) Keys() []Value {
-       tk := v.Type().(*MapType).Key()
-       m := *(**byte)(v.addr)
-       mlen := int32(0)
-       if m != nil {
-               mlen = maplen(m)
+       if cap < 0 {
+               panic("reflect.MakeSlice: negative cap")
        }
-       it := mapiterinit(m)
-       a := make([]Value, mlen)
-       var i int
-       for i = 0; i < len(a); i++ {
-               k := MakeZero(tk)
-               if !mapiterkey(it, (*byte)(k.getAddr())) {
-                       break
-               }
-               a[i] = k
-               mapiternext(it)
+       if len > cap {
+               panic("reflect.MakeSlice: len > cap")
        }
-       return a[0:i]
-}
 
-// MakeMap creates a new map of the specified type.
-func MakeMap(typ *MapType) *MapValue {
-       v := MakeZero(typ).(*MapValue)
-       *(**byte)(v.addr) = makemap((*runtime.MapType)(unsafe.Pointer(typ)))
-       return v
-}
+       // Declare slice so that gc can see the base pointer in it.
+       var x []byte
 
-/*
- * ptr
- */
+       // Reinterpret as *SliceHeader to edit.
+       s := (*SliceHeader)(unsafe.Pointer(&x))
+       s.Data = uintptr(unsafe_NewArray(typ.Elem(), cap))
+       s.Len = len
+       s.Cap = cap
 
-// A PtrValue represents a pointer.
-type PtrValue struct {
-       value "ptr"
+       return Value{typ.common(), unsafe.Pointer(&x), flagIndir | flag(Slice)<<flagKindShift}
 }
 
-// IsNil returns whether v is a nil pointer.
-func (v *PtrValue) IsNil() bool { return *(*uintptr)(v.addr) == 0 }
-
-// Get returns the uintptr value of v.
-// It is mainly useful for printing.
-func (v *PtrValue) Get() uintptr { return *(*uintptr)(v.addr) }
-
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *PtrValue) Set(x *PtrValue) {
-       if x == nil {
-               *(**uintptr)(v.addr) = nil
-               return
-       }
-       if !v.canSet {
-               panic(cannotSet)
-       }
-       typesMustMatch(v.typ, x.typ)
-       // TODO: This will have to move into the runtime
-       // once the new gc goes in
-       *(*uintptr)(v.addr) = *(*uintptr)(x.addr)
-}
-
-// Set sets v to the value x.
-func (v *PtrValue) SetValue(x Value) {
-       if x == nil {
-               v.Set(nil)
-               return
+// 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")
        }
-       v.Set(x.(*PtrValue))
-}
-
-// PointTo changes v to point to x.
-// If x is a nil Value, PointTo sets v to nil.
-func (v *PtrValue) PointTo(x Value) {
-       if x == nil {
-               *(**uintptr)(v.addr) = nil
-               return
+       if buffer < 0 {
+               panic("reflect.MakeChan: negative buffer size")
        }
-       if !x.CanSet() {
-               panic("cannot set x; cannot point to x")
+       if typ.ChanDir() != BothDir {
+               panic("reflect.MakeChan: unidirectional channel type")
        }
-       typesMustMatch(v.typ.(*PtrType).Elem(), x.Type())
-       // TODO: This will have to move into the runtime
-       // once the new gc goes in.
-       *(*uintptr)(v.addr) = x.Addr()
+       ch := makechan(typ.runtimeType(), uint32(buffer))
+       return Value{typ.common(), unsafe.Pointer(ch), flagIndir | (flag(Chan) << flagKindShift)}
 }
 
-// Elem returns the value that v points to.
-// If v is a nil pointer, Elem returns a nil Value.
-func (v *PtrValue) Elem() Value {
-       if v.IsNil() {
-               return nil
+// 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")
        }
-       return newValue(v.typ.(*PtrType).Elem(), *(*addr)(v.addr), v.canSet)
+       m := makemap(typ.runtimeType())
+       return Value{typ.common(), unsafe.Pointer(m), flagIndir | (flag(Map) << flagKindShift)}
 }
 
 // Indirect returns the value that v points to.
-// If v is a nil pointer, Indirect returns a nil Value.
+// If v is a nil pointer, Indirect returns a zero Value.
 // If v is not a pointer, Indirect returns v.
 func Indirect(v Value) Value {
-       if pv, ok := v.(*PtrValue); ok {
-               return pv.Elem()
+       if v.Kind() != Ptr {
+               return v
        }
-       return v
+       return v.Elem()
 }
 
-/*
- * struct
- */
+// 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{}
+       }
 
-// A StructValue represents a struct value.
-type StructValue struct {
-       value "struct"
-}
+       // TODO(rsc): Eliminate this terrible hack.
+       // In the call to packValue, eface.typ doesn't escape,
+       // and eface.word is an integer.  So it looks like
+       // i (= eface) doesn't escape.  But really it does,
+       // because eface.word is actually a pointer.
+       escapes(i)
 
-// Set assigns x to v.
-// The new value x must have the same type as v.
-func (v *StructValue) Set(x *StructValue) {
-       // TODO: This will have to move into the runtime
-       // once the gc goes in.
-       if !v.canSet {
-               panic(cannotSet)
+       // For an interface value with the noAddr bit set,
+       // the representation is identical to an empty interface.
+       eface := *(*emptyInterface)(unsafe.Pointer(&i))
+       typ := toCommonType(eface.typ)
+       fl := flag(typ.Kind()) << flagKindShift
+       if typ.Kind() != Ptr && typ.Kind() != UnsafePointer {
+               fl |= flagIndir
        }
-       typesMustMatch(v.typ, x.typ)
-       memmove(v.addr, x.addr, v.typ.Size())
+       return Value{typ, unsafe.Pointer(eface.word), fl}
 }
 
-// Set sets v to the value x.
-func (v *StructValue) SetValue(x Value) { v.Set(x.(*StructValue)) }
-
-// Field returns the i'th field of the struct.
-func (v *StructValue) Field(i int) Value {
-       t := v.typ.(*StructType)
-       if i < 0 || i >= t.NumField() {
-               return nil
+// Zero returns a Value representing the 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.
+// The returned value is neither addressable nor settable.
+func Zero(typ Type) Value {
+       if typ == nil {
+               panic("reflect: Zero(nil)")
        }
-       f := t.Field(i)
-       return newValue(f.Type, addr(uintptr(v.addr)+f.Offset), v.canSet && f.PkgPath == "")
+       t := typ.common()
+       fl := flag(t.Kind()) << flagKindShift
+       if t.Kind() == Ptr || t.Kind() == UnsafePointer {
+               return Value{t, nil, fl}
+       }
+       return Value{t, unsafe_New(typ), fl | flagIndir}
 }
 
-// FieldByIndex returns the nested field corresponding to index.
-func (t *StructValue) FieldByIndex(index []int) (v Value) {
-       v = t
-       for i, x := range index {
-               if i > 0 {
-                       if p, ok := v.(*PtrValue); ok {
-                               v = p.Elem()
-                       }
-                       if s, ok := v.(*StructValue); ok {
-                               t = s
-                       } else {
-                               v = nil
-                               return
-                       }
-               }
-               v = t.Field(x)
+// 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)")
        }
-       return
+       ptr := unsafe_New(typ)
+       fl := flag(Ptr) << flagKindShift
+       return Value{typ.common().ptrTo(), ptr, fl}
 }
 
-// FieldByName returns the struct field with the given name.
-// The result is nil if no field was found.
-func (t *StructValue) FieldByName(name string) Value {
-       if f, ok := t.Type().(*StructType).FieldByName(name); ok {
-               return t.FieldByIndex(f.Index)
-       }
-       return nil
+// NewAt returns a Value representing a pointer to a value of the
+// specified type, using p as that pointer.
+func NewAt(typ Type, p unsafe.Pointer) Value {
+       fl := flag(Ptr) << flagKindShift
+       return Value{typ.common().ptrTo(), p, fl}
 }
 
-// FieldByNameFunc returns the struct field with a name that satisfies the
-// match function.
-// The result is nil if no field was found.
-func (t *StructValue) FieldByNameFunc(match func(string) bool) Value {
-       if f, ok := t.Type().(*StructType).FieldByNameFunc(match); ok {
-               return t.FieldByIndex(f.Index)
+// assignTo returns a value v that can be assigned directly to typ.
+// It panics if v is not assignable to typ.
+// For a conversion to an interface type, target is a suggested scratch space to use.
+func (v Value) assignTo(context string, dst *commonType, target *interface{}) Value {
+       if v.flag&flagMethod != 0 {
+               panic(context + ": cannot assign method value to type " + dst.String())
+       }
+
+       switch {
+       case directlyAssignable(dst, v.typ):
+               // Overwrite type so that they match.
+               // Same memory layout, so no harm done.
+               v.typ = dst
+               fl := v.flag & (flagRO | flagAddr | flagIndir)
+               fl |= flag(dst.Kind()) << flagKindShift
+               return Value{dst, v.val, fl}
+
+       case implements(dst, v.typ):
+               if target == nil {
+                       target = new(interface{})
+               }
+               x := valueInterface(v, false)
+               if dst.NumMethod() == 0 {
+                       *target = x
+               } else {
+                       ifaceE2I(dst.runtimeType(), x, unsafe.Pointer(target))
+               }
+               return Value{dst, unsafe.Pointer(target), flagIndir | flag(Interface)<<flagKindShift}
        }
-       return nil
+
+       // Failed.
+       panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
 }
 
-// NumField returns the number of fields in the struct.
-func (v *StructValue) NumField() int { return v.typ.(*StructType).NumField() }
+// implemented in ../pkg/runtime
+func chancap(ch iword) int32
+func chanclose(ch iword)
+func chanlen(ch iword) int32
+func chanrecv(t *runtimeType, ch iword, nb bool) (val iword, selected, received bool)
+func chansend(t *runtimeType, ch iword, val iword, nb bool) bool
 
-/*
- * constructors
- */
+func makechan(typ *runtimeType, size uint32) (ch iword)
+func makemap(t *runtimeType) (m iword)
+func mapaccess(t *runtimeType, m iword, key iword) (val iword, ok bool)
+func mapassign(t *runtimeType, m iword, key, val iword, ok bool)
+func mapiterinit(t *runtimeType, m iword) *byte
+func mapiterkey(it *byte) (key iword, ok bool)
+func mapiternext(it *byte)
+func maplen(m iword) int32
 
-// NewValue returns a new Value initialized to the concrete value
-// stored in the interface i.  NewValue(nil) returns nil.
-func NewValue(i interface{}) Value {
-       if i == nil {
-               return nil
-       }
-       t, a := unsafe.Reflect(i)
-       return newValue(canonicalize(toType(t)), addr(a), true)
-}
-
-func newValue(typ Type, addr addr, canSet bool) Value {
-       v := value{typ, addr, canSet}
-       switch typ.(type) {
-       case *ArrayType:
-               return &ArrayValue{v}
-       case *BoolType:
-               return &BoolValue{v}
-       case *ChanType:
-               return &ChanValue{v}
-       case *FloatType:
-               return &FloatValue{v}
-       case *FuncType:
-               return &FuncValue{value: v}
-       case *ComplexType:
-               return &ComplexValue{v}
-       case *IntType:
-               return &IntValue{v}
-       case *InterfaceType:
-               return &InterfaceValue{v}
-       case *MapType:
-               return &MapValue{v}
-       case *PtrType:
-               return &PtrValue{v}
-       case *SliceType:
-               return &SliceValue{v}
-       case *StringType:
-               return &StringValue{v}
-       case *StructType:
-               return &StructValue{v}
-       case *UintType:
-               return &UintValue{v}
-       case *UnsafePointerType:
-               return &UnsafePointerValue{v}
-       }
-       panic("newValue" + typ.String())
-}
-
-// MakeZero returns a zero Value for the specified Type.
-func MakeZero(typ Type) Value {
-       if typ == nil {
-               return nil
+func call(typ *commonType, fnaddr unsafe.Pointer, isInterface bool, isMethod bool, params *unsafe.Pointer, results *unsafe.Pointer)
+func ifaceE2I(t *runtimeType, src interface{}, dst unsafe.Pointer)
+
+// Dummy annotation marking that the value x escapes,
+// for use in cases where the reflect code is so clever that
+// the compiler cannot follow.
+func escapes(x interface{}) {
+       if dummy.b {
+               dummy.x = x
        }
-       return newValue(typ, addr(unsafe.New(typ)), true)
+}
+
+var dummy struct {
+       b bool
+       x interface{}
 }