install new reflect:
rename ntype.go and nvalue.go to type.go and value.go

R=r
DELTA=4295  (761 added, 2819 deleted, 715 changed)
OCL=31238
CL=31276
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index 26ba6cb..69e1eb3 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Reflection library.
-// Handling values.
-
 package reflect
 
 import (
@@ -12,1002 +9,952 @@
 	"unsafe";
 )
 
-// Addr is shorthand for unsafe.Pointer and is used to represent the address of Values.
-type Addr unsafe.Pointer
+const cannotSet = "cannot set value obtained via unexported struct field"
 
-func equalType(a, b Type) bool {
-	return a.Kind() == b.Kind() && a.String() == b.String()
-}
-
-// Value is the generic interface to reflection values.  Once its Kind is known,
-// such as BoolKind, the Value can be narrowed to the appropriate, more
-// specific interface, such as BoolValue.  Such narrowed values still implement
-// the Value interface.
-type Value interface {
-	// The kind of thing described: ArrayKind, BoolKind, etc.
-	Kind()	int;
-	// The reflection Type of the value.
-	Type()	Type;
-	// The address of the value.
-	Addr()	Addr;
-	// The value itself is the dynamic value of an empty interface.
-	Interface()	interface {};
-}
-
-func NewValue(e interface{}) Value;
-
-// commonValue fields and functionality for all values
-
-type commonValue struct {
-	kind	int;
-	typ	Type;
-	addr	Addr;
-}
-
-func (c *commonValue) Kind() int {
-	return c.kind
-}
-
-func (c *commonValue) Type() Type {
-	return c.typ
-}
-
-func (c *commonValue) Addr() Addr {
-	return c.addr
-}
-
-func (c *commonValue) Interface() interface {} {
-	var i interface {};
+// TODO: This will have to go away when
+// the new gc goes in.
+func memmove(dst, src, n uintptr) {
+	var p uintptr;	// dummy for sizeof
+	const ptrsize = uintptr(unsafe.Sizeof(p));
 	switch {
-	case c.typ.Kind() == InterfaceKind:
-		panic("not reached");	// InterfaceValue overrides this method
-	case c.typ.Size() > unsafe.Sizeof(uintptr(0)):
-		i = unsafe.Unreflect(uint64(uintptr(c.addr)), c.typ.String(), true);
-	default:
-		if uintptr(c.addr) == 0 {
-			panicln("reflect: address 0 for", c.typ.String());
+	case src < dst && src+n > dst:
+		// byte copy backward
+		// careful: i is unsigned
+		for i := n; i > 0; {
+			i--;
+			*(*byte)(addr(dst+i)) = *(*byte)(addr(src+i));
 		}
-		i = unsafe.Unreflect(uint64(uintptr(*(*Addr)(c.addr))), c.typ.String(), false);
+	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));
+		}
+	default:
+		// word copy forward
+		for i := uintptr(0); i < n; i += ptrsize {
+			*(*uintptr)(addr(dst+i)) = *(*uintptr)(addr(src+i));
+		}
 	}
-	return i;
 }
 
-func newValueAddr(typ Type, addr Addr) Value
+// 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;
 
-type creatorFn func(typ Type, addr Addr) Value
+	// 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;
 
-// -- Missing
-
-// MissingValue represents a value whose type is not known. It usually
-// indicates an error.
-type MissingValue interface {
-	Value;
+	// Addr returns a pointer to the underlying data.
+	// It is for advanced clients that also
+	// import the "unsafe" package.
+	Addr()	uintptr;
 }
 
-type missingValueStruct struct {
-	commonValue
+type value struct {
+	typ Type;
+	addr addr;
+	canSet bool;
 }
 
-func missingCreator(typ Type, addr Addr) Value {
-	return &missingValueStruct{ commonValue{MissingKind, typ, addr} }
+func (v *value) Type() Type {
+	return v.typ
 }
 
-// -- Int
-
-// IntValue represents an int value.
-type IntValue interface {
-	Value;
-	Get()	int;	// Get the underlying int.
-	Set(int);	// Set the underlying int.
+func (v *value) Addr() uintptr {
+	return uintptr(v.addr);
 }
 
-type intValueStruct struct {
-	commonValue
-}
+type InterfaceValue struct
+type StructValue struct
 
-func intCreator(typ Type, addr Addr) Value {
-	return &intValueStruct{ commonValue{IntKind, typ, addr} }
-}
-
-func (v *intValueStruct) Get() int {
-	return *(*int)(v.addr)
-}
-
-func (v *intValueStruct) Set(i int) {
-	*(*int)(v.addr) = i
-}
-
-// -- Int8
-
-// Int8Value represents an int8 value.
-type Int8Value interface {
-	Value;
-	Get()	int8;	// Get the underlying int8.
-	Set(int8);	// Set the underlying int8.
-}
-
-type int8ValueStruct struct {
-	commonValue
-}
-
-func int8Creator(typ Type, addr Addr) Value {
-	return &int8ValueStruct{ commonValue{Int8Kind, typ, addr} }
-}
-
-func (v *int8ValueStruct) Get() int8 {
-	return *(*int8)(v.addr)
-}
-
-func (v *int8ValueStruct) Set(i int8) {
-	*(*int8)(v.addr) = i
-}
-
-// -- Int16
-
-// Int16Value represents an int16 value.
-type Int16Value interface {
-	Value;
-	Get()	int16;	// Get the underlying int16.
-	Set(int16);	// Set the underlying int16.
-}
-
-type int16ValueStruct struct {
-	commonValue
-}
-
-func int16Creator(typ Type, addr Addr) Value {
-	return &int16ValueStruct{ commonValue{Int16Kind, typ, addr} }
-}
-
-func (v *int16ValueStruct) Get() int16 {
-	return *(*int16)(v.addr)
-}
-
-func (v *int16ValueStruct) Set(i int16) {
-	*(*int16)(v.addr) = i
-}
-
-// -- Int32
-
-// Int32Value represents an int32 value.
-type Int32Value interface {
-	Value;
-	Get()	int32;	// Get the underlying int32.
-	Set(int32);	// Set the underlying int32.
-}
-
-type int32ValueStruct struct {
-	commonValue
-}
-
-func int32Creator(typ Type, addr Addr) Value {
-	return &int32ValueStruct{ commonValue{Int32Kind, typ, addr} }
-}
-
-func (v *int32ValueStruct) Get() int32 {
-	return *(*int32)(v.addr)
-}
-
-func (v *int32ValueStruct) Set(i int32) {
-	*(*int32)(v.addr) = i
-}
-
-// -- Int64
-
-// Int64Value represents an int64 value.
-type Int64Value interface {
-	Value;
-	Get()	int64;	// Get the underlying int64.
-	Set(int64);	// Set the underlying int64.
-}
-
-type int64ValueStruct struct {
-	commonValue
-}
-
-func int64Creator(typ Type, addr Addr) Value {
-	return &int64ValueStruct{ commonValue{Int64Kind, typ, addr} }
-}
-
-func (v *int64ValueStruct) Get() int64 {
-	return *(*int64)(v.addr)
-}
-
-func (v *int64ValueStruct) Set(i int64) {
-	*(*int64)(v.addr) = i
-}
-
-// -- Uint
-
-// UintValue represents a uint value.
-type UintValue interface {
-	Value;
-	Get()	uint;	// Get the underlying uint.
-	Set(uint);	// Set the underlying uint.
-}
-
-type uintValueStruct struct {
-	commonValue
-}
-
-func uintCreator(typ Type, addr Addr) Value {
-	return &uintValueStruct{ commonValue{UintKind, typ, addr} }
-}
-
-func (v *uintValueStruct) Get() uint {
-	return *(*uint)(v.addr)
-}
-
-func (v *uintValueStruct) Set(i uint) {
-	*(*uint)(v.addr) = i
-}
-
-// -- Uint8
-
-// Uint8Value represents a uint8 value.
-type Uint8Value interface {
-	Value;
-	Get()	uint8;	// Get the underlying uint8.
-	Set(uint8);	// Set the underlying uint8.
-}
-
-type uint8ValueStruct struct {
-	commonValue
-}
-
-func uint8Creator(typ Type, addr Addr) Value {
-	return &uint8ValueStruct{ commonValue{Uint8Kind, typ, addr} }
-}
-
-func (v *uint8ValueStruct) Get() uint8 {
-	return *(*uint8)(v.addr)
-}
-
-func (v *uint8ValueStruct) Set(i uint8) {
-	*(*uint8)(v.addr) = i
-}
-
-// -- Uint16
-
-// Uint16Value represents a uint16 value.
-type Uint16Value interface {
-	Value;
-	Get()	uint16;	// Get the underlying uint16.
-	Set(uint16);	// Set the underlying uint16.
-}
-
-type uint16ValueStruct struct {
-	commonValue
-}
-
-func uint16Creator(typ Type, addr Addr) Value {
-	return &uint16ValueStruct{ commonValue{Uint16Kind, typ, addr} }
-}
-
-func (v *uint16ValueStruct) Get() uint16 {
-	return *(*uint16)(v.addr)
-}
-
-func (v *uint16ValueStruct) Set(i uint16) {
-	*(*uint16)(v.addr) = i
-}
-
-// -- Uint32
-
-// Uint32Value represents a uint32 value.
-type Uint32Value interface {
-	Value;
-	Get()	uint32;	// Get the underlying uint32.
-	Set(uint32);	// Set the underlying uint32.
-}
-
-type uint32ValueStruct struct {
-	commonValue
-}
-
-func uint32Creator(typ Type, addr Addr) Value {
-	return &uint32ValueStruct{ commonValue{Uint32Kind, typ, addr} }
-}
-
-func (v *uint32ValueStruct) Get() uint32 {
-	return *(*uint32)(v.addr)
-}
-
-func (v *uint32ValueStruct) Set(i uint32) {
-	*(*uint32)(v.addr) = i
-}
-
-// -- Uint64
-
-// Uint64Value represents a uint64 value.
-type Uint64Value interface {
-	Value;
-	Get()	uint64;	// Get the underlying uint64.
-	Set(uint64);	// Set the underlying uint64.
-}
-
-type uint64ValueStruct struct {
-	commonValue
-}
-
-func uint64Creator(typ Type, addr Addr) Value {
-	return &uint64ValueStruct{ commonValue{Uint64Kind, typ, addr} }
-}
-
-func (v *uint64ValueStruct) Get() uint64 {
-	return *(*uint64)(v.addr)
-}
-
-func (v *uint64ValueStruct) Set(i uint64) {
-	*(*uint64)(v.addr) = i
-}
-
-// -- Uintptr
-
-// UintptrValue represents a uintptr value.
-type UintptrValue interface {
-	Value;
-	Get()	uintptr;	// Get the underlying uintptr.
-	Set(uintptr);	// Set the underlying uintptr.
-}
-
-type uintptrValueStruct struct {
-	commonValue
-}
-
-func uintptrCreator(typ Type, addr Addr) Value {
-	return &uintptrValueStruct{ commonValue{UintptrKind, typ, addr} }
-}
-
-func (v *uintptrValueStruct) Get() uintptr {
-	return *(*uintptr)(v.addr)
-}
-
-func (v *uintptrValueStruct) Set(i uintptr) {
-	*(*uintptr)(v.addr) = i
-}
-
-// -- Float
-
-// FloatValue represents a float value.
-type FloatValue interface {
-	Value;
-	Get()	float;	// Get the underlying float.
-	Set(float);	// Get the underlying float.
-}
-
-type floatValueStruct struct {
-	commonValue
-}
-
-func floatCreator(typ Type, addr Addr) Value {
-	return &floatValueStruct{ commonValue{FloatKind, typ, addr} }
-}
-
-func (v *floatValueStruct) Get() float {
-	return *(*float)(v.addr)
-}
-
-func (v *floatValueStruct) Set(f float) {
-	*(*float)(v.addr) = f
-}
-
-// -- Float32
-
-// Float32Value represents a float32 value.
-type Float32Value interface {
-	Value;
-	Get()	float32;	// Get the underlying float32.
-	Set(float32);	// Get the underlying float32.
-}
-
-type float32ValueStruct struct {
-	commonValue
-}
-
-func float32Creator(typ Type, addr Addr) Value {
-	return &float32ValueStruct{ commonValue{Float32Kind, typ, addr} }
-}
-
-func (v *float32ValueStruct) Get() float32 {
-	return *(*float32)(v.addr)
-}
-
-func (v *float32ValueStruct) Set(f float32) {
-	*(*float32)(v.addr) = f
-}
-
-// -- Float64
-
-// Float64Value represents a float64 value.
-type Float64Value interface {
-	Value;
-	Get()	float64;	// Get the underlying float64.
-	Set(float64);	// Get the underlying float64.
-}
-
-type float64ValueStruct struct {
-	commonValue
-}
-
-func float64Creator(typ Type, addr Addr) Value {
-	return &float64ValueStruct{ commonValue{Float64Kind, typ, addr} }
-}
-
-func (v *float64ValueStruct) Get() float64 {
-	return *(*float64)(v.addr)
-}
-
-func (v *float64ValueStruct) Set(f float64) {
-	*(*float64)(v.addr) = f
-}
-
-// -- String
-
-// StringValue represents a string value.
-type StringValue interface {
-	Value;
-	Get()	string;	// Get the underlying string value.
-	Set(string);	// Set the underlying string value.
-}
-
-type stringValueStruct struct {
-	commonValue
-}
-
-func stringCreator(typ Type, addr Addr) Value {
-	return &stringValueStruct{ commonValue{StringKind, typ, addr} }
-}
-
-func (v *stringValueStruct) Get() string {
-	return *(*string)(v.addr)
-}
-
-func (v *stringValueStruct) Set(s string) {
-	*(*string)(v.addr) = s
-}
-
-// -- Bool
-
-// BoolValue represents a bool value.
-type BoolValue interface {
-	Value;
-	Get()	bool;	// Get the underlying bool value.
-	Set(bool);	// Set the underlying bool value.
-}
-
-type boolValueStruct struct {
-	commonValue
-}
-
-func boolCreator(typ Type, addr Addr) Value {
-	return &boolValueStruct{ commonValue{BoolKind, typ, addr} }
-}
-
-func (v *boolValueStruct) Get() bool {
-	return *(*bool)(v.addr)
-}
-
-func (v *boolValueStruct) Set(b bool) {
-	*(*bool)(v.addr) = b
-}
-
-// -- Pointer
-
-// PtrValue represents a pointer value.
-type PtrValue interface {
-	Value;
-	Sub()	Value;	// The Value pointed to.
-	Get()	Addr;	// Get the address stored in the pointer.
-	SetSub(Value);	// Set the the pointed-to Value.
-	IsNil() bool;
-}
-
-type ptrValueStruct struct {
-	commonValue
-}
-
-func (v *ptrValueStruct) Get() Addr {
-	return *(*Addr)(v.addr)
-}
-
-func (v *ptrValueStruct) IsNil() bool {
-	return uintptr(*(*Addr)(v.addr)) == 0
-}
-
-func (v *ptrValueStruct) Sub() Value {
-	if v.IsNil() {
-		return nil
+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)
 	}
-	return newValueAddr(v.typ.(PtrType).Sub(), v.Get());
+	return unsafe.Unreflect(v.typ, unsafe.Pointer(v.addr));
 }
 
-func (v *ptrValueStruct) SetSub(subv Value) {
-	a := v.typ.(PtrType).Sub();
-	b := subv.Type();
-	if !equalType(a, b) {
-		panicln("reflect: incompatible types in PtrValue.SetSub:",
-			a.String(), b.String());
-	}
-	*(*Addr)(v.addr) = subv.Addr();
+func (v *value) CanSet() bool {
+	return v.canSet;
 }
 
-func ptrCreator(typ Type, addr Addr) Value {
-	return &ptrValueStruct{ commonValue{PtrKind, typ, addr} };
-}
-
-// -- Array
-// Slices and arrays are represented by the same interface.
-
-// ArrayValue represents an array or slice value.
-type ArrayValue interface {
-	Value;
-	IsSlice()	bool;	// Is this a slice (true) or array (false)?
-	Len()	int;	// The length of the array/slice.
-	Cap() int;	// The capacity of the array/slice (==Len() for arrays).
-	Elem(i int)	Value;	// The Value of the i'th element.
-	SetLen(len int);	// Set the length; slice only.
-	Set(src ArrayValue);	// Set the underlying Value; slice only for src and dest both.
-	CopyFrom(src ArrayValue, n int);	// Copy the elements from src; lengths must match.
-	IsNil() bool;
-}
-
-func copyArray(dst ArrayValue, src ArrayValue, n int);
+func newValue(typ Type, addr addr, canSet bool) Value
+func NewValue(i interface{}) Value
 
 /*
-	Run-time representation of slices looks like this:
-		struct	Slice {
-			byte*	array;		// actual data
-			uint32	nel;		// number of elements
-			uint32	cap;
-		};
-*/
+ * basic types
+ */
 
-// A published version of the Slice header so that clients don't have a separate copy of the definition.
-// SliceHeader is not useful to clients unless they use unsafe.Pointer.
+// BoolValue represents a bool value.
+type BoolValue struct {
+	value;
+}
+
+// Get returns the underlying bool value.
+func (v *BoolValue) Get() bool {
+	return *(*bool)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *BoolValue) Set(x bool) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*bool)(v.addr) = x;
+}
+
+// FloatValue represents a float value.
+type FloatValue struct {
+	value;
+}
+
+// Get returns the underlying float value.
+func (v *FloatValue) Get() float {
+	return *(*float)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *FloatValue) Set(x float) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*float)(v.addr) = x;
+}
+
+// Float32Value represents a float32 value.
+type Float32Value struct {
+	value;
+}
+
+// Get returns the underlying float32 value.
+func (v *Float32Value) Get() float32 {
+	return *(*float32)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Float32Value) Set(x float32) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*float32)(v.addr) = x;
+}
+
+// Float64Value represents a float64 value.
+type Float64Value struct {
+	value;
+}
+
+// Get returns the underlying float64 value.
+func (v *Float64Value) Get() float64 {
+	return *(*float64)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Float64Value) Set(x float64) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*float64)(v.addr) = x;
+}
+
+// IntValue represents an int value.
+type IntValue struct {
+	value;
+}
+
+// Get returns the underlying int value.
+func (v *IntValue) Get() int {
+	return *(*int)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *IntValue) Set(x int) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*int)(v.addr) = x;
+}
+
+// Int8Value represents an int8 value.
+type Int8Value struct {
+	value;
+}
+
+// Get returns the underlying int8 value.
+func (v *Int8Value) Get() int8 {
+	return *(*int8)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Int8Value) Set(x int8) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*int8)(v.addr) = x;
+}
+
+// Int16Value represents an int16 value.
+type Int16Value struct {
+	value;
+}
+
+// Get returns the underlying int16 value.
+func (v *Int16Value) Get() int16 {
+	return *(*int16)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Int16Value) Set(x int16) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*int16)(v.addr) = x;
+}
+
+// Int32Value represents an int32 value.
+type Int32Value struct {
+	value;
+}
+
+// Get returns the underlying int32 value.
+func (v *Int32Value) Get() int32 {
+	return *(*int32)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Int32Value) Set(x int32) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*int32)(v.addr) = x;
+}
+
+// Int64Value represents an int64 value.
+type Int64Value struct {
+	value;
+}
+
+// Get returns the underlying int64 value.
+func (v *Int64Value) Get() int64 {
+	return *(*int64)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Int64Value) Set(x int64) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*int64)(v.addr) = x;
+}
+
+// StringValue represents a string value.
+type StringValue struct {
+	value;
+}
+
+// Get returns the underlying string value.
+func (v *StringValue) Get() string {
+	return *(*string)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *StringValue) Set(x string) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*string)(v.addr) = x;
+}
+
+// UintValue represents a uint value.
+type UintValue struct {
+	value;
+}
+
+// Get returns the underlying uint value.
+func (v *UintValue) Get() uint {
+	return *(*uint)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *UintValue) Set(x uint) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uint)(v.addr) = x;
+}
+
+// Uint8Value represents a uint8 value.
+type Uint8Value struct {
+	value;
+}
+
+// Get returns the underlying uint8 value.
+func (v *Uint8Value) Get() uint8 {
+	return *(*uint8)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Uint8Value) Set(x uint8) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uint8)(v.addr) = x;
+}
+
+// Uint16Value represents a uint16 value.
+type Uint16Value struct {
+	value;
+}
+
+// Get returns the underlying uint16 value.
+func (v *Uint16Value) Get() uint16 {
+	return *(*uint16)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Uint16Value) Set(x uint16) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uint16)(v.addr) = x;
+}
+
+// Uint32Value represents a uint32 value.
+type Uint32Value struct {
+	value;
+}
+
+// Get returns the underlying uint32 value.
+func (v *Uint32Value) Get() uint32 {
+	return *(*uint32)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Uint32Value) Set(x uint32) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uint32)(v.addr) = x;
+}
+
+// Uint64Value represents a uint64 value.
+type Uint64Value struct {
+	value;
+}
+
+// Get returns the underlying uint64 value.
+func (v *Uint64Value) Get() uint64 {
+	return *(*uint64)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *Uint64Value) Set(x uint64) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uint64)(v.addr) = x;
+}
+
+// UintptrValue represents a uintptr value.
+type UintptrValue struct {
+	value;
+}
+
+// Get returns the underlying uintptr value.
+func (v *UintptrValue) Get() uintptr {
+	return *(*uintptr)(v.addr);
+}
+
+// Set sets v to the value x.
+func (v *UintptrValue) Set(x uintptr) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	*(*uintptr)(v.addr) = x;
+}
+
+// UnsafePointerValue represents an unsafe.Pointer value.
+type UnsafePointerValue struct {
+	value;
+}
+
+// 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);
+	}
+	*(*unsafe.Pointer)(v.addr) = x;
+}
+
+func typesMustMatch(t1, t2 reflect.Type) {
+	if t1 != t2 {
+		panicln("type mismatch:", t1, "!=", t2);
+	}
+}
+
+/*
+ * 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;
+}
+
+// ArrayCopy 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 ArrayCopy(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;
+	}
+	memmove(uintptr(dst.addr()), uintptr(src.addr()), uintptr(n) * de.Size());
+	return n;
+}
+
+// An ArrayValue represents an array.
+type ArrayValue struct {
+	value
+}
+
+// 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);
+	}
+	typesMustMatch(v.typ, x.typ);
+	ArrayCopy(v, x);
+}
+
+// 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("index", i, "in array len", n);
+	}
+	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	uint32;
-	Cap	uint32;
+	Data uintptr;
+	Len uint32;
+	Cap uint32;
 }
 
-type sliceValueStruct struct {
-	commonValue;
-	elemtype	Type;
-	elemsize	int;
-	slice *SliceHeader;
+// A SliceValue represents a slice.
+type SliceValue struct {
+	value
 }
 
-func (v *sliceValueStruct) IsSlice() bool {
-	return true
+func (v *SliceValue) slice() *SliceHeader {
+	return (*SliceHeader)(v.value.addr);
 }
 
-func (v *sliceValueStruct) Len() int {
-	return int(v.slice.Len);
+// IsNil returns whether v is a nil slice.
+func (v *SliceValue) IsNil() bool {
+	return v.slice().Data == 0;
 }
 
-func (v *sliceValueStruct) Cap() int {
-	return int(v.slice.Cap);
+// Len returns the length of the slice.
+func (v *SliceValue) Len() int {
+	return int(v.slice().Len);
 }
 
-func (v *sliceValueStruct) SetLen(len int) {
-	if len > v.Cap() {
-		panicln("reflect: sliceValueStruct.SetLen", len, v.Cap());
+// 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();
+	if n < 0 || n > int(s.Cap) {
+		panicln("SetLen", n, "with capacity", s.Cap);
 	}
-	v.slice.Len = uint32(len);
+	s.Len = uint32(n);
 }
 
-func (v *sliceValueStruct) Set(src ArrayValue) {
-	if !src.IsSlice() {
-		panic("can't set slice from array");
+// 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);
 	}
-	s := src.(*sliceValueStruct);
-	if !equalType(v.typ, s.typ) {
-		panicln("incompatible types in ArrayValue.Set()");
+	typesMustMatch(v.typ, x.typ);
+	*v.slice() = *x.slice();
+}
+
+// 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 bounds [", beg, ":", end, "] with capacity ", cap);
 	}
-	*v.slice = *s.slice;
+	typ := v.typ.(*SliceType);
+	s := new(SliceHeader);
+	s.Data = uintptr(v.addr()) + uintptr(beg) * typ.Elem().Size();
+	s.Len = uint32(end - beg);
+	s.Cap = uint32(cap - beg);
+	return newValue(typ, addr(s), v.canSet).(*SliceValue);
 }
 
-func (v *sliceValueStruct) Elem(i int) Value {
-	data_uint := v.slice.Data + uintptr(i * v.elemsize);
-	return newValueAddr(v.elemtype, Addr(data_uint));
-}
-
-func (v *sliceValueStruct) CopyFrom(src ArrayValue, n int) {
-	copyArray(v, src, n);
-}
-
-func (v *sliceValueStruct) IsNil() bool {
-	return v.slice.Data == 0
-}
-
-type arrayValueStruct struct {
-	commonValue;
-	elemtype	Type;
-	elemsize	int;
-	len	int;
-}
-
-func (v *arrayValueStruct) IsSlice() bool {
-	return false
-}
-
-func (v *arrayValueStruct) Len() int {
-	return v.len
-}
-
-func (v *arrayValueStruct) Cap() int {
-	return v.len
-}
-
-func (v *arrayValueStruct) SetLen(len int) {
-	panicln("can't set len of array");
-}
-
-func (v *arrayValueStruct) Set(src ArrayValue) {
-	panicln("can't set array");
-}
-
-func (v *arrayValueStruct) Elem(i int) Value {
-	data_uint := uintptr(v.addr) + uintptr(i * v.elemsize);
-	return newValueAddr(v.elemtype, Addr(data_uint));
-}
-
-func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
-	copyArray(v, src, n);
-}
-
-func (v *arrayValueStruct) IsNil() bool {
-	return false
-}
-
-func arrayCreator(typ Type, addr Addr) Value {
-	arraytype := typ.(ArrayType);
-	if arraytype.IsSlice() {
-		v := new(sliceValueStruct);
-		v.kind = ArrayKind;
-		v.addr = addr;
-		v.typ = typ;
-		v.elemtype = arraytype.Elem();
-		v.elemsize = v.elemtype.Size();
-		v.slice = (*SliceHeader)(addr);
-		return v;
+// 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 {
+		panicln("index", i, "in array of length", n);
 	}
-	v := new(arrayValueStruct);
-	v.kind = ArrayKind;
-	v.addr = addr;
-	v.typ = typ;
-	v.elemtype = arraytype.Elem();
-	v.elemsize = v.elemtype.Size();
-	v.len = arraytype.Len();
+	p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size());
+	return newValue(typ, p, v.canSet);
+}
+
+// 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 := new(SliceHeader);
+	size := typ.Elem().Size() * uintptr(cap);
+	if size == 0 {
+		size = 1;
+	}
+	data := make([]uint8, size);
+	s.Data = uintptr(addr(&data[0]));
+	s.Len = uint32(len);
+	s.Cap = uint32(cap);
+	return newValue(typ, addr(s), true).(*SliceValue);
+}
+
+/*
+ * chan
+ */
+
+// A ChanValue represents a chan.
+type ChanValue struct {
+	value
+}
+
+// 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);
+	}
+	typesMustMatch(v.typ, x.typ);
+	*(*uintptr)(v.addr) = *(*uintptr)(x.addr);
+}
+
+// Get returns the uintptr value of v.
+// It is mainly useful for printing.
+func (v *ChanValue) Get() uintptr {
+	return *(*uintptr)(v.addr);
+}
+
+// Send sends x on the channel v.
+func (v *ChanValue) Send(x Value) {
+	panic("unimplemented: channel Send");
+}
+
+// Recv receives and returns a value from the channel v.
+func (v *ChanValue) Recv() Value {
+	panic("unimplemented: channel Receive");
+}
+
+// TrySend attempts to sends x on the channel v but will not block.
+// It returns true if the value was sent, false otherwise.
+func (v *ChanValue) TrySend(x Value) bool {
+	panic("unimplemented: channel TrySend");
+}
+
+// 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 {
+	panic("unimplemented: channel TryRecv");
+}
+
+/*
+ * func
+ */
+
+// A FuncValue represents a function value.
+type FuncValue struct {
+	value
+}
+
+// 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);
+}
+
+// Call calls the function v with input parameters in.
+// It returns the function's output parameters as Values.
+func (v *FuncValue) Call(in []Value) []Value {
+	panic("unimplemented: function Call");
+}
+
+
+/*
+ * interface
+ */
+
+// An InterfaceValue represents an interface value.
+type InterfaceValue struct {
+	value
+}
+
+// No Get because v.Interface() is available.
+
+// IsNil returns whether v is a nil interface value.
+func (v *InterfaceValue) IsNil() bool {
+	return v.Interface() == nil;
+}
+
+// Elem returns the concrete value stored in the interface value v.
+func (v *InterfaceValue) Elem() Value {
+	return NewValue(v.Interface());
+}
+
+// Set assigns x to v.
+func (v *InterfaceValue) Set(x interface{}) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	// Two different representations; see comment in Get.
+	// Empty interface is easy.
+	if v.typ.(*InterfaceType).NumMethod() == 0 {
+		*(*interface{})(v.addr) = x;
+	}
+
+	// Non-empty interface requires a runtime check.
+	panic("unimplemented: interface Set");
+//	unsafe.SetInterface(v.typ, v.addr, x);
+}
+
+/*
+ * map
+ */
+
+// A MapValue represents a map value.
+type MapValue struct {
+	value
+}
+
+// IsNil returns whether v is a nil map value.
+func (v *MapValue) 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 *MapValue) Set(x *MapValue) {
+	if !v.canSet {
+		panic(cannotSet);
+	}
+	typesMustMatch(v.typ, x.typ);
+	*(*uintptr)(v.addr) = *(*uintptr)(x.addr);
+}
+
+// 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 {
+	panic("unimplemented: map Elem");
+}
+
+// Len returns the number of keys in the map v.
+func (v *MapValue) Len() int {
+	panic("unimplemented: map Len");
+}
+
+// Keys returns a slice containing all the keys present in the map,
+// in unspecified order.
+func (v *MapValue) Keys() []Value {
+	panic("unimplemented: map Keys");
+}
+
+/*
+ * ptr
+ */
+
+// A PtrValue represents a pointer.
+type PtrValue struct {
+	value
+}
+
+// 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 !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);
+}
+
+// PointTo changes v to point to x.
+func (v *PtrValue) PointTo(x Value) {
+	if !x.CanSet() {
+		panic("cannot set x; cannot point to x");
+	}
+	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();
+}
+
+// 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;
+	}
+	return newValue(v.typ.(*PtrType).Elem(), *(*addr)(v.addr), v.canSet);
+}
+
+// Indirect returns the value that v points to.
+// If v is a nil pointer, Indirect returns a nil Value.
+// If v is not a pointer, Indirect returns v.
+func Indirect(v Value) Value {
+	if pv, ok := v.(*PtrValue); ok {
+		return pv.Elem();
+	}
 	return v;
 }
 
-// -- Map	TODO: finish and test
+/*
+ * struct
+ */
 
-// MapValue represents a map value.
-// Its implementation is incomplete.
-type MapValue interface {
-	Value;
-	Len()	int;	// The number of elements; currently always returns 0.
-	Elem(key Value)	Value;	// The value indexed by key; unimplemented.
-	IsNil() bool;
+// A StructValue represents a struct value.
+type StructValue struct {
+	value
 }
 
-type mapValueStruct struct {
-	commonValue
-}
-
-func mapCreator(typ Type, addr Addr) Value {
-	return &mapValueStruct{ commonValue{MapKind, typ, addr} }
-}
-
-func (v *mapValueStruct) Len() int {
-	return 0	// TODO: probably want this to be dynamic
-}
-
-func (v *mapValueStruct) IsNil() bool {
-	return false	// TODO: implement this properly
-}
-
-func (v *mapValueStruct) Elem(key Value) Value {
-	panic("map value element");
-	return nil
-}
-
-// -- Chan
-
-// ChanValue represents a chan value.
-// Its implementation is incomplete.
-type ChanValue interface {
-	Value;
-	IsNil() bool;
-}
-
-type chanValueStruct struct {
-	commonValue
-}
-
-func (v *chanValueStruct) IsNil() bool {
-	return false	// TODO: implement this properly
-}
-
-func chanCreator(typ Type, addr Addr) Value {
-	return &chanValueStruct{ commonValue{ChanKind, typ, addr} }
-}
-
-// -- Struct
-
-// StructValue represents a struct value.
-type StructValue interface {
-	Value;
-	Len()	int;	// The number of fields.
-	Field(i int)	Value;	// The Value of field i.
-}
-
-type structValueStruct struct {
-	commonValue;
-	field	[]Value;
-}
-
-func (v *structValueStruct) Len() int {
-	return len(v.field)
-}
-
-func (v *structValueStruct) Field(i int) Value {
-	return v.field[i]
-}
-
-func structCreator(typ Type, addr Addr) Value {
-	t := typ.(StructType);
-	nfield := t.Len();
-	v := &structValueStruct{ commonValue{StructKind, typ, addr}, make([]Value, nfield) };
-	for i := 0; i < nfield; i++ {
-		name, ftype, str, offset := t.Field(i);
-		addr_uint := uintptr(addr) + uintptr(offset);
-		v.field[i] = newValueAddr(ftype, Addr(addr_uint));
+// 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);
 	}
-	v.typ = typ;
-	return v;
+	typesMustMatch(v.typ, x.typ);
+	memmove(uintptr(v.addr), uintptr(x.addr), v.typ.Size());
 }
 
-// -- Interface
-
-// InterfaceValue represents an interface value.
-type InterfaceValue interface {
-	Value;
-	Get()	interface {};	// Get the underlying interface{} value.
-	Value() Value;
-	IsNil() bool;
-}
-
-type interfaceValueStruct struct {
-	commonValue
-}
-
-func (v *interfaceValueStruct) Get() interface{} {
-	// 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 v.Type().(InterfaceType).Len() == 0 {
-		// Extract as interface value without methods.
-		return *(*interface{})(v.addr)
+// 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;
 	}
-	// Extract from v.addr as interface value with methods.
-	return *(*interface{ m() })(v.addr)
+	f := t.Field(i);
+	return newValue(f.Type, addr(uintptr(v.addr)+f.Offset), v.canSet && f.PkgPath == "");
 }
 
-func (v *interfaceValueStruct) Interface() interface{} {
-	return v.Get();
+// NumField returns the number of fields in the struct.
+func (v *StructValue) NumField() int {
+	return v.typ.(*StructType).NumField();
 }
 
-func (v *interfaceValueStruct) Value() Value {
-	i := v.Get();
+/*
+ * constructors
+ */
+
+// Typeof returns the reflection Type of the value in the interface{}.
+func Typeof(i interface{}) Type {
+	return toType(unsafe.Typeof(i));
+}
+
+// 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;
 	}
-	return NewValue(i);
+	t, a := unsafe.Reflect(i);
+	return newValue(toType(t), addr(a), true);
 }
 
-func (v *interfaceValueStruct) IsNil() bool {
-	return *(*interface{})(v.addr) == nil
-}
-
-func interfaceCreator(typ Type, addr Addr) Value {
-	return &interfaceValueStruct{ commonValue{InterfaceKind, typ, addr} }
-}
-
-// -- Func
-
-
-// FuncValue represents a func value.
-// Its implementation is incomplete.
-type FuncValue interface {
-	Value;
-	Get()	Addr;	// The address of the function.
-	IsNil() bool;
-}
-
-type funcValueStruct struct {
-	commonValue
-}
-
-func (v *funcValueStruct) Get() Addr {
-	return *(*Addr)(v.addr)
-}
-
-func (v *funcValueStruct) IsNil() bool {
-	return *(*Addr)(v.addr) == nil
-}
-
-func funcCreator(typ Type, addr Addr) Value {
-	return &funcValueStruct{ commonValue{FuncKind, typ, addr} }
-}
-
-var creator = map[int] creatorFn {
-	MissingKind : missingCreator,
-	IntKind : intCreator,
-	Int8Kind : int8Creator,
-	Int16Kind : int16Creator,
-	Int32Kind : int32Creator,
-	Int64Kind : int64Creator,
-	UintKind : uintCreator,
-	Uint8Kind : uint8Creator,
-	Uint16Kind : uint16Creator,
-	Uint32Kind : uint32Creator,
-	Uint64Kind : uint64Creator,
-	UintptrKind : uintptrCreator,
-	FloatKind : floatCreator,
-	Float32Kind : float32Creator,
-	Float64Kind : float64Creator,
-	StringKind : stringCreator,
-	BoolKind : boolCreator,
-	PtrKind : ptrCreator,
-	ArrayKind : arrayCreator,
-	MapKind : mapCreator,
-	ChanKind : chanCreator,
-	StructKind : structCreator,
-	InterfaceKind : interfaceCreator,
-	FuncKind : funcCreator,
-}
-
-var typecache = make(map[string] Type);
-
-func newValueAddr(typ Type, addr Addr) Value {
-	c, ok := creator[typ.Kind()];
-	if !ok {
-		panicln("no creator for type" , typ.String());
+func newValue(typ Type, addr addr, canSet bool) Value {
+	// All values have same memory layout;
+	// build once and convert.
+	v := &struct{value}{value{typ, addr, canSet}};
+	switch t := typ.(type) {	// TODO(rsc): s/t := // ?
+	case *ArrayType:
+		// TODO(rsc): Something must prevent
+		// clients of the package from doing
+		// this same kind of cast.
+		// We should be allowed because
+		// they're our types.
+		// Something about implicit assignment
+		// to struct fields.
+		return (*ArrayValue)(v);
+	case *BoolType:
+		return (*BoolValue)(v);
+	case *ChanType:
+		return (*ChanValue)(v);
+	case *FloatType:
+		return (*FloatValue)(v);
+	case *Float32Type:
+		return (*Float32Value)(v);
+	case *Float64Type:
+		return (*Float64Value)(v);
+	case *FuncType:
+		return (*FuncValue)(v);
+	case *IntType:
+		return (*IntValue)(v);
+	case *Int8Type:
+		return (*Int8Value)(v);
+	case *Int16Type:
+		return (*Int16Value)(v);
+	case *Int32Type:
+		return (*Int32Value)(v);
+	case *Int64Type:
+		return (*Int64Value)(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 *Uint8Type:
+		return (*Uint8Value)(v);
+	case *Uint16Type:
+		return (*Uint16Value)(v);
+	case *Uint32Type:
+		return (*Uint32Value)(v);
+	case *Uint64Type:
+		return (*Uint64Value)(v);
+	case *UintptrType:
+		return (*UintptrValue)(v);
+	case *UnsafePointerType:
+		return (*UnsafePointerValue)(v);
 	}
-	return c(typ, addr);
+	panicln("newValue", typ.String());
 }
 
-// NewZeroValue creates a new, zero-initialized Value for the specified Type.
-func NewZeroValue(typ Type) Value {
+func newFuncValue(typ Type, addr addr) *FuncValue {
+	return newValue(typ, addr, true).(*FuncValue);
+}
+
+// MakeZeroValue returns a zero Value for the specified Type.
+func MakeZero(typ Type) Value {
+	// TODO: this will have to move into
+	// the runtime proper in order to play nicely
+	// with the garbage collector.
 	size := typ.Size();
 	if size == 0 {
 		size = 1;
 	}
 	data := make([]uint8, size);
-	return newValueAddr(typ, Addr(&data[0]));
-}
-
-// NewSliceValue creates a new, zero-initialized slice value (ArrayValue) for the specified
-// slice type (ArrayType), length, and capacity.
-func NewSliceValue(typ ArrayType, len, cap int) ArrayValue {
-	if !typ.IsSlice() {
-		return nil
-	}
-
-	array := new(SliceHeader);
-	size := typ.Elem().Size() * cap;
-	if size == 0 {
-		size = 1;
-	}
-	data := make([]uint8, size);
-	array.Data = uintptr(Addr(&data[0]));
-	array.Len = uint32(len);
-	array.Cap = uint32(cap);
-
-	return newValueAddr(typ, Addr(array)).(ArrayValue);
-}
-
-// Works on both slices and arrays
-func copyArray(dst ArrayValue, src ArrayValue, n int) {
-	if n == 0 {
-		return
-	}
-	dt := dst.Type().(ArrayType).Elem();
-	st := src.Type().(ArrayType).Elem();
-	if !equalType(dt, st) {
-		panicln("reflect: incompatible types in CopyArray:",
-			dt.String(), st.String());
-	}
-	if n < 0 || n > dst.Len() || n > src.Len() {
-		panicln("reflect: CopyArray: invalid count", n);
-	}
-	dstp := uintptr(dst.Elem(0).Addr());
-	srcp := uintptr(src.Elem(0).Addr());
-	end := uintptr(n)*uintptr(dt.Size());
-	if end % 8 == 0 {
-		for i := uintptr(0); i < end; i += 8{
-			di := Addr(dstp + i);
-			si := Addr(srcp + i);
-			*(*uint64)(di) = *(*uint64)(si);
-		}
-	} else {
-		for i := uintptr(0); i < end; i++ {
-			di := Addr(dstp + i);
-			si := Addr(srcp + i);
-			*(*byte)(di) = *(*byte)(si);
-		}
-	}
-}
-
-func typeof(typestring string) Type {
-	typ, ok := typecache[typestring];
-	if !ok {
-		typ = ParseTypeString("", typestring);
-		if typ.Kind() == MissingKind {
-			// This can not happen: unsafe.Reflect should only
-			// ever tell us the names of types that exist.
-			// Of course it does happen, and when it does
-			// it is more helpful to catch it in action here than
-			// to see $missing$ in a later print.
-			panicln("missing type for", typestring);
-		}
-		typecache[typestring] = typ;
-	}
-	return typ;
-}
-
-// NewValue creates a new Value from the interface{} object provided.
-func NewValue(e interface {}) Value {
-	value, typestring, indir := unsafe.Reflect(e);
-	typ := typeof(typestring);
-	var ap Addr;
-	if indir {
-		// Content of interface is large and didn't
-		// fit, so it's a pointer to the actual content.
-		// We have an address, but we need to
-		// make a copy to avoid letting the caller
-		// edit the content inside the interface.
-		n := uintptr(typ.Size());
-		data := make([]byte, n);
-		p1 := uintptr(Addr(&data[0]));
-		p2 := uintptr(value);
-		for i := uintptr(0); i < n; i++ {
-			*(*byte)(Addr(p1+i)) = *(*byte)(Addr(p2+i));
-		}
-		ap = Addr(&data[0]);
-	} else {
-		// Content of interface is small and stored
-		// inside the interface.  Make a copy so we
-		// can take its address.
-		x := new(uint64);
-		*x = value;
-		ap = Addr(x);
-	}
-	return newValueAddr(typ, ap);
-}
-
-// Typeof returns the type of the value in the interface{} object provided.
-func Typeof(e interface{}) Type {
-	value, typestring, indir := unsafe.Reflect(e);
-	return typeof(typestring);
-}
-
-// Indirect indirects one level through a value, if it is a pointer.
-// If not a pointer, the value is returned unchanged.
-// Useful when walking arbitrary data structures.
-func Indirect(v Value) Value {
-	if v.Kind() == PtrKind {
-		p := v.(PtrValue);
-		if p.Get() == nil {
-			return nil
-		}
-		v = p.Sub()
-	}
-	return v
+	return newValue(typ, addr(&data[0]), true);
 }