]> Cypherpunks repositories - gostls13.git/commitdiff
install new reflect:
authorRuss Cox <rsc@golang.org>
Tue, 7 Jul 2009 18:02:44 +0000 (11:02 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 7 Jul 2009 18:02:44 +0000 (11:02 -0700)
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

src/pkg/Make.deps
src/pkg/reflect/ntype.go [deleted file]
src/pkg/reflect/nvalue.go [deleted file]
src/pkg/reflect/type.go
src/pkg/reflect/value.go

index 84e6b131671ce8a5b39ce0a92f6b6e882203a48f..088708fba58f7ee0598f8b3486414ddf2a56bed0 100644 (file)
@@ -38,7 +38,7 @@ once.install: sync.install
 os.install: once.install syscall.install
 path.install: strings.install
 rand.install:
-reflect.install: strconv.install sync.install utf8.install
+reflect.install: runtime.install strconv.install strings.install
 regexp.install: bytes.install container/vector.install io.install os.install runtime.install utf8.install
 runtime.install:
 sort.install:
diff --git a/src/pkg/reflect/ntype.go b/src/pkg/reflect/ntype.go
deleted file mode 100644 (file)
index 5041e6a..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reflect
-
-import (
-       "runtime";
-       "strconv";
-       "strings";
-       "unsafe";
-)
-
-/*
- * Copy of data structures from ../runtime/type.go.
- * For comments, see the ones in that file.
- *
- * These data structures are known to the compiler and the runtime.
- *
- * Putting these types in runtime instead of reflect means that
- * reflect doesn't need to be autolinked into every binary, which
- * simplifies bootstrapping and package dependencies.
- * Unfortunately, it also means that reflect needs its own
- * copy in order to access the private fields.
- */
-
-type uncommonType struct
-
-type commonType struct {
-       size uintptr;
-       hash uint32;
-       alg uint8;
-       align uint8;
-       fieldAlign uint8;
-       string *string;
-       *uncommonType;
-}
-
-type method struct {
-       hash uint32;
-       name *string;
-       pkgPath *string;
-       typ *runtime.Type;
-       ifn unsafe.Pointer;
-       tfn unsafe.Pointer;
-}
-
-type uncommonType struct {
-       name *string;
-       pkgPath *string;
-       methods []method;
-}
-
-// BoolType represents a boolean type.
-type BoolType struct {
-       commonType
-}
-
-// Float32Type represents a float32 type.
-type Float32Type struct {
-       commonType
-}
-
-// Float64Type represents a float64 type.
-type Float64Type struct {
-       commonType
-}
-
-// FloatType represents a float type.
-type FloatType struct {
-       commonType
-}
-
-// Int16Type represents an int16 type.
-type Int16Type struct {
-       commonType
-}
-
-// Int32Type represents an int32 type.
-type Int32Type struct {
-       commonType
-}
-
-// Int64Type represents an int64 type.
-type Int64Type struct {
-       commonType
-}
-
-// Int8Type represents an int8 type.
-type Int8Type struct {
-       commonType
-}
-
-// IntType represents an int type.
-type IntType struct {
-       commonType
-}
-
-// Uint16Type represents a uint16 type.
-type Uint16Type struct {
-       commonType
-}
-
-// Uint32Type represents a uint32 type.
-type Uint32Type struct {
-       commonType
-}
-
-// Uint64Type represents a uint64 type.
-type Uint64Type struct {
-       commonType
-}
-
-// Uint8Type represents a uint8 type.
-type Uint8Type struct {
-       commonType
-}
-
-// UintType represents a uint type.
-type UintType struct {
-       commonType
-}
-
-// StringType represents a string type.
-type StringType struct {
-       commonType
-}
-
-// UintptrType represents a uintptr type.
-type UintptrType struct {
-       commonType
-}
-
-// DotDotDotType represents the ... that can
-// be used as the type of the final function parameter.
-type DotDotDotType struct {
-       commonType
-}
-
-// UnsafePointerType represents an unsafe.Pointer type.
-type UnsafePointerType struct {
-       commonType
-}
-
-// ArrayType represents a fixed array type.
-type ArrayType struct {
-       commonType;
-       elem *runtime.Type;
-       len uintptr;
-}
-
-// ChanDir represents a channel type's direction.
-type ChanDir int
-const (
-       RecvDir ChanDir = 1<<iota;
-       SendDir;
-       BothDir = RecvDir | SendDir;
-)
-
-// ChanType represents a channel type.
-type ChanType struct {
-       commonType;
-       elem *runtime.Type;
-       dir uintptr;
-}
-
-// FuncType represents a function type.
-type FuncType struct {
-       commonType;
-       in []*runtime.Type;
-       out []*runtime.Type;
-}
-
-// Method on interface type
-type imethod struct {
-       hash uint32;
-       perm uint32;
-       name *string;
-       pkgPath *string;
-       typ *runtime.Type;
-}
-
-// InterfaceType represents an interface type.
-type InterfaceType struct {
-       commonType;
-       methods []imethod;
-}
-
-// MapType represents a map type.
-type MapType struct {
-       commonType;
-       key *runtime.Type;
-       elem *runtime.Type;
-}
-
-// PtrType represents a pointer type.
-type PtrType struct {
-       commonType;
-       elem *runtime.Type;
-}
-
-// SliceType represents a slice type.
-type SliceType struct {
-       commonType;
-       elem *runtime.Type;
-}
-
-// Struct field
-type structField struct {
-       name *string;
-       pkgPath *string;
-       typ *runtime.Type;
-       tag *string;
-       offset uintptr;
-}
-
-// StructType represents a struct type.
-type StructType struct {
-       commonType;
-       fields []structField;
-}
-
-
-/*
- * The compiler knows the exact layout of all the data structures above.
- * The compiler does not know about the data structures and methods below.
- */
-
-type Type interface
-type addr unsafe.Pointer
-type FuncValue struct
-func newFuncValue(typ Type, addr addr) *FuncValue
-
-// Method represents a single method.
-type Method struct {
-       PkgPath string;         // empty for uppercase Name
-       Name string;
-       Type *FuncType;
-       Func *FuncValue;
-}
-
-// Type is the runtime representation of a Go type.
-// Every type implements the methods listed here.
-// Some types implement additional interfaces;
-// use a type switch to find out what kind of type a Type is.
-// Each type in a program has a unique Type, so == on Types
-// corresponds to Go's type equality.
-type Type interface {
-       // Name returns the type's package and name.
-       // The package is a full package import path like "container/vector".
-       Name()  (pkgPath string, name string);
-
-       // String returns a string representation of the type.
-       // The string representation may use shortened package names
-       // (e.g., vector instead of "container/vector") and is not
-       // guaranteed to be unique among types.  To test for equality,
-       // compare the Types directly.
-       String()        string;
-
-       // Size returns the number of bytes needed to store
-       // a value of the given type; it is analogous to unsafe.Sizeof.
-       Size()  uintptr;
-
-       // Align returns the alignment of a value of this type
-       // when allocated in memory.
-       Align() int;
-
-       // FieldAlign returns the alignment of a value of this type
-       // when used as a field in a struct.
-       FieldAlign()    int;
-
-       // For non-interface types, Method returns the i'th method with receiver T.
-       // For interface types, Method returns the i'th method in the interface.
-       // NumMethod returns the number of such methods.
-       Method(int)     Method;
-       NumMethod()     int;
-}
-
-func toType(i interface{}) Type
-
-func (t *uncommonType) Name() (pkgPath string, name string) {
-       if t == nil {
-               return;
-       }
-       if t.pkgPath != nil {
-               pkgPath = *t.pkgPath;
-       }
-       if t.name != nil {
-               name = *t.name;
-       }
-       return;
-}
-
-func (t *commonType) String() string {
-       return *t.string;
-}
-
-func (t *commonType) Size() uintptr {
-       return t.size;
-}
-
-func (t *commonType) Align() int {
-       return int(t.align);
-}
-
-func (t *commonType) FieldAlign() int {
-       return int(t.fieldAlign);
-}
-
-func (t *uncommonType) Method(i int) (m Method) {
-       if t == nil || i < 0 || i >= len(t.methods) {
-               return;
-       }
-       p := &t.methods[i];
-       if p.name != nil {
-               m.Name = *p.name;
-       }
-       if p.pkgPath != nil {
-               m.PkgPath = *p.pkgPath;
-       }
-       m.Type = toType(*p.typ).(*FuncType);
-       fn := p.tfn;
-       m.Func = newFuncValue(m.Type, addr(&fn));
-       return;
-}
-
-func (t *uncommonType) NumMethod() int {
-       if t == nil {
-               return 0;
-       }
-       return len(t.methods);
-}
-
-// TODO(rsc): 6g supplies these, but they are not
-// as efficient as they could be: they have commonType
-// as the receiver instead of *commonType.
-func (t *commonType) NumMethod() int {
-       return t.uncommonType.NumMethod();
-}
-
-func (t *commonType) Method(i int) (m Method) {
-       return t.uncommonType.Method(i);
-}
-
-func (t *commonType) Name() (pkgPath string, name string) {
-       return t.uncommonType.Name();
-}
-
-// Len returns the number of elements in the array.
-func (t *ArrayType) Len() int {
-       return int(t.len);
-}
-
-// Elem returns the type of the array's elements.
-func (t *ArrayType) Elem() Type {
-       return toType(*t.elem);
-}
-
-// Dir returns the channel direction.
-func (t *ChanType) Dir() ChanDir {
-       return ChanDir(t.dir);
-}
-
-// Elem returns the channel's element type.
-func (t *ChanType) Elem() Type {
-       return toType(*t.elem);
-}
-
-func (d ChanDir) String() string {
-       switch d {
-       case SendDir:
-               return "chan<-";
-       case RecvDir:
-               return "<-chan";
-       case BothDir:
-               return "chan";
-       }
-       return "ChanDir" + strconv.Itoa(int(d));
-}
-
-// In returns the type of the i'th function input parameter.
-func (t *FuncType) In(i int) Type {
-       if i < 0 || i >= len(t.in) {
-               return nil;
-       }
-       return toType(*t.in[i]);
-}
-
-// NumIn returns the number of input parameters.
-func (t *FuncType) NumIn() int {
-       return len(t.in);
-}
-
-// Out returns the type of the i'th function output parameter.
-func (t *FuncType) Out(i int) Type {
-       if i < 0 || i >= len(t.out) {
-               return nil;
-       }
-       return toType(*t.out[i]);
-}
-
-// NumOut returns the number of function output parameters.
-func (t *FuncType) NumOut() int {
-       return len(t.out);
-}
-
-// Method returns the i'th interface method.
-func (t *InterfaceType) Method(i int) (m Method) {
-       if i < 0 || i >= len(t.methods) {
-               return;
-       }
-       p := t.methods[i];
-       m.Name = *p.name;
-       if p.pkgPath != nil {
-               m.PkgPath = *p.pkgPath;
-       }
-       m.Type = toType(*p.typ).(*FuncType);
-       return;
-}
-
-// NumMethod returns the number of interface methods.
-func (t *InterfaceType) NumMethod() int {
-       return len(t.methods);
-}
-
-// Key returns the map key type.
-func (t *MapType) Key() Type {
-       return toType(*t.key);
-}
-
-// Elem returns the map element type.
-func (t *MapType) Elem() Type {
-       return toType(*t.elem);
-}
-
-// Elem returns the pointer element type.
-func (t *PtrType) Elem() Type {
-       return toType(*t.elem);
-}
-
-// Elem returns the type of the slice's elements.
-func (t *SliceType) Elem() Type {
-       return toType(*t.elem);
-}
-
-type StructField struct {
-       PkgPath string;         // empty for uppercase Name
-       Name string;
-       Type Type;
-       Tag string;
-       Offset uintptr;
-       Anonymous bool;
-}
-
-// Field returns the i'th struct field.
-func (t *StructType) Field(i int) (f StructField) {
-       if i < 0 || i >= len(t.fields) {
-               return;
-       }
-       p := t.fields[i];
-       f.Type = toType(*p.typ);
-       if p.name != nil {
-               f.Name = *p.name;
-       } else {
-               nam, pkg := f.Type.Name();
-               f.Name = nam;
-               f.Anonymous = true;
-       }
-       if p.pkgPath != nil {
-               f.PkgPath = *p.pkgPath;
-       }
-       if p.tag != nil {
-               f.Tag = *p.tag;
-       }
-       f.Offset = p.offset;
-       return;
-}
-
-// NumField returns the number of struct fields.
-func (t *StructType) NumField() int {
-       return len(t.fields);
-}
-
-// Convert runtime type to reflect type.
-// Same memory layouts, different method sets.
-func toType(i interface{}) Type {
-       switch v := i.(type) {
-       case *runtime.BoolType:
-               return (*BoolType)(unsafe.Pointer(v));
-       case *runtime.DotDotDotType:
-               return (*DotDotDotType)(unsafe.Pointer(v));
-       case *runtime.FloatType:
-               return (*FloatType)(unsafe.Pointer(v));
-       case *runtime.Float32Type:
-               return (*Float32Type)(unsafe.Pointer(v));
-       case *runtime.Float64Type:
-               return (*Float64Type)(unsafe.Pointer(v));
-       case *runtime.IntType:
-               return (*IntType)(unsafe.Pointer(v));
-       case *runtime.Int8Type:
-               return (*Int8Type)(unsafe.Pointer(v));
-       case *runtime.Int16Type:
-               return (*Int16Type)(unsafe.Pointer(v));
-       case *runtime.Int32Type:
-               return (*Int32Type)(unsafe.Pointer(v));
-       case *runtime.Int64Type:
-               return (*Int64Type)(unsafe.Pointer(v));
-       case *runtime.StringType:
-               return (*StringType)(unsafe.Pointer(v));
-       case *runtime.UintType:
-               return (*UintType)(unsafe.Pointer(v));
-       case *runtime.Uint8Type:
-               return (*Uint8Type)(unsafe.Pointer(v));
-       case *runtime.Uint16Type:
-               return (*Uint16Type)(unsafe.Pointer(v));
-       case *runtime.Uint32Type:
-               return (*Uint32Type)(unsafe.Pointer(v));
-       case *runtime.Uint64Type:
-               return (*Uint64Type)(unsafe.Pointer(v));
-       case *runtime.UintptrType:
-               return (*UintptrType)(unsafe.Pointer(v));
-       case *runtime.UnsafePointerType:
-               return (*UnsafePointerType)(unsafe.Pointer(v));
-       case *runtime.ArrayType:
-               return (*ArrayType)(unsafe.Pointer(v));
-       case *runtime.ChanType:
-               return (*ChanType)(unsafe.Pointer(v));
-       case *runtime.FuncType:
-               return (*FuncType)(unsafe.Pointer(v));
-       case *runtime.InterfaceType:
-               return (*InterfaceType)(unsafe.Pointer(v));
-       case *runtime.MapType:
-               return (*MapType)(unsafe.Pointer(v));
-       case *runtime.PtrType:
-               return (*PtrType)(unsafe.Pointer(v));
-       case *runtime.SliceType:
-               return (*SliceType)(unsafe.Pointer(v));
-       case *runtime.StructType:
-               return (*StructType)(unsafe.Pointer(v));
-       }
-       panicln("toType", i);
-}
-
-// ArrayOrSliceType is the common interface implemented
-// by both ArrayType and SliceType.
-type ArrayOrSliceType interface {
-       Type;
-       Elem() Type;
-}
-
-
diff --git a/src/pkg/reflect/nvalue.go b/src/pkg/reflect/nvalue.go
deleted file mode 100644 (file)
index ac7b7d7..0000000
+++ /dev/null
@@ -1,960 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reflect
-
-import (
-       "reflect";
-       "unsafe";
-)
-
-const cannotSet = "cannot set value obtained via unexported struct field"
-
-// 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 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));
-               }
-       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));
-               }
-       }
-}
-
-// 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;
-
-       // Addr returns a pointer to the underlying data.
-       // It is for advanced clients that also
-       // import the "unsafe" package.
-       Addr()  uintptr;
-}
-
-type value struct {
-       typ Type;
-       addr addr;
-       canSet bool;
-}
-
-func (v *value) Type() Type {
-       return v.typ
-}
-
-func (v *value) Addr() uintptr {
-       return uintptr(v.addr);
-}
-
-type InterfaceValue struct
-type StructValue struct
-
-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 unsafe.Unreflect(v.typ, unsafe.Pointer(v.addr));
-}
-
-func (v *value) CanSet() bool {
-       return v.canSet;
-}
-
-func newValue(typ Type, addr addr, canSet bool) Value
-func NewValue(i interface{}) Value
-
-/*
- * basic types
- */
-
-// 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;
-}
-
-// A SliceValue represents a slice.
-type SliceValue struct {
-       value
-}
-
-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();
-       if n < 0 || n > int(s.Cap) {
-               panicln("SetLen", n, "with capacity", s.Cap);
-       }
-       s.Len = uint32(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);
-       }
-       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);
-       }
-       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);
-}
-
-// 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);
-       }
-       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;
-}
-
-/*
- * struct
- */
-
-// A StructValue represents a struct value.
-type StructValue struct {
-       value
-}
-
-// 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);
-       }
-       typesMustMatch(v.typ, x.typ);
-       memmove(uintptr(v.addr), uintptr(x.addr), v.typ.Size());
-}
-
-// 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;
-       }
-       f := t.Field(i);
-       return newValue(f.Type, addr(uintptr(v.addr)+f.Offset), v.canSet && f.PkgPath == "");
-}
-
-// NumField returns the number of fields in the struct.
-func (v *StructValue) NumField() int {
-       return v.typ.(*StructType).NumField();
-}
-
-/*
- * 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;
-       }
-       t, a := unsafe.Reflect(i);
-       return newValue(toType(t), addr(a), true);
-}
-
-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);
-       }
-       panicln("newValue", typ.String());
-}
-
-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 newValue(typ, addr(&data[0]), true);
-}
index 3ff191727b68e99a20fe00d03af58ae7f4e34db2..ccbd472d88b55d8d7e21bf394eb78efa91c2d989 100644 (file)
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Reflection library.
-// Types and parsing of type strings.
-
-// This package implements data ``reflection''.  A program can use it to analyze types
-// and values it does not know at compile time, such as the values passed in a call
-// to a function with a ... parameter.  This is achieved by extracting the dynamic
-// contents of an interface value.
 package reflect
 
 import (
-       "sync";
+       "runtime";
+       "strconv";
+       "strings";
        "unsafe";
-       "utf8";
-)
-
-type Type interface
-
-func ExpandType(name string) Type
-
-func typestrings() string      // implemented in C; declared here
-
-// These constants identify what kind of thing a Type represents: an int, struct, etc.
-const (
-       MissingKind = iota;
-       ArrayKind;
-       BoolKind;
-       ChanKind;
-       DotDotDotKind;
-       FloatKind;
-       Float32Kind;
-       Float64Kind;
-       FuncKind;
-       IntKind;
-       Int16Kind;
-       Int32Kind;
-       Int64Kind;
-       Int8Kind;
-       InterfaceKind;
-       MapKind;
-       PtrKind;
-       StringKind;
-       StructKind;
-       UintKind;
-       Uint16Kind;
-       Uint32Kind;
-       Uint64Kind;
-       Uint8Kind;
-       UintptrKind;
 )
 
-// For sizes and alignments.
-
-type allTypes struct {
-       xarray          []byte;
-       xbool           bool;
-       xchan           chan byte;
-       xfloat          float;
-       xfloat32        float32;
-       xfloat64        float64;
-       xfunc           func();
-       xint            int;
-       xint16          int16;
-       xint32          int32;
-       xint64          int64;
-       xint8           int8;
-       xinterface      interface {};
-       xmap            map[byte]byte;
-       xptr            *byte;
-       xslice          []byte;
-       xstring         string;
-       xuint           uint;
-       xuint16         uint16;
-       xuint32         uint32;
-       xuint64         uint64;
-       xuint8          uint8;
-       xuintptr        uintptr;
-}
-
-var (
-       x allTypes;
-       minStruct struct { uint8 };
-)
-
-const (
-       minStructAlignMask = unsafe.Sizeof(minStruct) - 1;
-       ptrsize = unsafe.Sizeof(&x);
-       interfacesize = unsafe.Sizeof(x.xinterface);
-)
-
-const missingString = "$missing$"      // syntactic name for undefined type names
-const dotDotDotString = "..."
-
-// Type is the generic interface to reflection types.  Once its Kind is known,
-// such as ArrayKind, the Type can be narrowed to the appropriate, more
-// specific interface, such as ArrayType.  Such narrowed types still implement
-// the Type interface.
-type Type interface {
-       // The kind of thing described: ArrayKind, BoolKind, etc.
-       Kind()  int;
-       // The name declared for the type ("int", "BoolArray", etc.).
-       Name()  string;
-       // For a named type, same as Name(); otherwise a representation of the type such as "[]int".
-       String()        string;
-       // The number of bytes needed to store a value; analogous to unsafe.Sizeof().
-       Size()  int;
-       // The alignment of a value of this type when used as a field in a struct.
-       FieldAlign()    int;
-}
+/*
+ * Copy of data structures from ../runtime/type.go.
+ * For comments, see the ones in that file.
+ *
+ * These data structures are known to the compiler and the runtime.
+ *
+ * Putting these types in runtime instead of reflect means that
+ * reflect doesn't need to be autolinked into every binary, which
+ * simplifies bootstrapping and package dependencies.
+ * Unfortunately, it also means that reflect needs its own
+ * copy in order to access the private fields.
+ */
+
+type uncommonType struct
 
-// Fields and methods common to all types
 type commonType struct {
-       kind    int;
-       str     string;
-       name    string;
-       size    int;
+       size uintptr;
+       hash uint32;
+       alg uint8;
+       align uint8;
+       fieldAlign uint8;
+       string *string;
+       *uncommonType;
 }
 
-func (c *commonType) Kind() int {
-       return c.kind
+type method struct {
+       hash uint32;
+       name *string;
+       pkgPath *string;
+       typ *runtime.Type;
+       ifn unsafe.Pointer;
+       tfn unsafe.Pointer;
 }
 
-func (c *commonType) Name() string {
-       return c.name
+type uncommonType struct {
+       name *string;
+       pkgPath *string;
+       methods []method;
 }
 
-func (c *commonType) String() string {
-       // If there is a name, show that instead of its expansion.
-       // This is important for reflection: a named type
-       // might have methods that the unnamed type does not.
-       if c.name != "" {
-               return c.name
-       }
-       return c.str
+// BoolType represents a boolean type.
+type BoolType struct {
+       commonType
 }
 
-func (c *commonType) Size() int {
-       return c.size
+// Float32Type represents a float32 type.
+type Float32Type struct {
+       commonType
 }
 
-// -- Basic
-
-type basicType struct {
-       commonType;
-       fieldAlign      int;
+// Float64Type represents a float64 type.
+type Float64Type struct {
+       commonType
 }
 
-func newBasicType(name string, kind int, size int, fieldAlign int) Type {
-       return &basicType{ commonType{kind, name, name, size}, fieldAlign }
+// FloatType represents a float type.
+type FloatType struct {
+       commonType
 }
 
-func (t *basicType) FieldAlign() int {
-       return t.fieldAlign
+// Int16Type represents an int16 type.
+type Int16Type struct {
+       commonType
 }
 
-// Prebuilt basic Type objects representing the predeclared basic types.
-// Most are self-evident except:
-//     Missing represents types whose representation cannot be discovered; usually an error.
-//     DotDotDot represents the pseudo-type of a ... parameter.
-var (
-       Missing = newBasicType(missingString, MissingKind, 1, 1);
-       DotDotDot = newBasicType(dotDotDotString, DotDotDotKind, unsafe.Sizeof(x.xinterface), unsafe.Alignof(x.xinterface));
-       Bool = newBasicType("bool", BoolKind, unsafe.Sizeof(x.xbool), unsafe.Alignof(x.xbool));
-       Int = newBasicType("int", IntKind, unsafe.Sizeof(x.xint), unsafe.Alignof(x.xint));
-       Int8 = newBasicType("int8", Int8Kind, unsafe.Sizeof(x.xint8), unsafe.Alignof(x.xint8));
-       Int16 = newBasicType("int16", Int16Kind, unsafe.Sizeof(x.xint16), unsafe.Alignof(x.xint16));
-       Int32 = newBasicType("int32", Int32Kind, unsafe.Sizeof(x.xint32), unsafe.Alignof(x.xint32));
-       Int64 = newBasicType("int64", Int64Kind, unsafe.Sizeof(x.xint64), unsafe.Alignof(x.xint64));
-       Uint = newBasicType("uint", UintKind, unsafe.Sizeof(x.xuint), unsafe.Alignof(x.xuint));
-       Uint8 = newBasicType("uint8", Uint8Kind, unsafe.Sizeof(x.xuint8), unsafe.Alignof(x.xuint8));
-       Uint16 = newBasicType("uint16", Uint16Kind, unsafe.Sizeof(x.xuint16), unsafe.Alignof(x.xuint16));
-       Uint32 = newBasicType("uint32", Uint32Kind, unsafe.Sizeof(x.xuint32), unsafe.Alignof(x.xuint32));
-       Uint64 = newBasicType("uint64", Uint64Kind, unsafe.Sizeof(x.xuint64), unsafe.Alignof(x.xuint64));
-       Uintptr = newBasicType("uintptr", UintptrKind, unsafe.Sizeof(x.xuintptr), unsafe.Alignof(x.xuintptr));
-       Float = newBasicType("float", FloatKind, unsafe.Sizeof(x.xfloat), unsafe.Alignof(x.xfloat));
-       Float32 = newBasicType("float32", Float32Kind, unsafe.Sizeof(x.xfloat32), unsafe.Alignof(x.xfloat32));
-       Float64 = newBasicType("float64", Float64Kind, unsafe.Sizeof(x.xfloat64), unsafe.Alignof(x.xfloat64));
-       String = newBasicType("string", StringKind, unsafe.Sizeof(x.xstring), unsafe.Alignof(x.xstring));
-)
-
-// Stub types allow us to defer evaluating type names until needed.
-// If the name is empty, the type must be non-nil.
-
-type stubType struct {
-       name    string;
-       typ             Type;
+// Int32Type represents an int32 type.
+type Int32Type struct {
+       commonType
 }
 
-func newStubType(name string, typ Type) *stubType {
-       return &stubType{name, typ}
+// Int64Type represents an int64 type.
+type Int64Type struct {
+       commonType
 }
 
-func (t *stubType) Get() Type {
-       if t.typ == nil {
-               t.typ = ExpandType(t.name)
-       }
-       return t.typ
+// Int8Type represents an int8 type.
+type Int8Type struct {
+       commonType
 }
 
-// -- Pointer
-
-// PtrType represents a pointer.
-type PtrType interface {
-       Type;
-       Sub()   Type    // The type of the pointed-to item; for "*int", it will be "int".
+// IntType represents an int type.
+type IntType struct {
+       commonType
 }
 
-type ptrTypeStruct struct {
-       commonType;
-       sub     *stubType;
+// Uint16Type represents a uint16 type.
+type Uint16Type struct {
+       commonType
 }
 
-func newPtrTypeStruct(name, typestring string, sub *stubType) *ptrTypeStruct {
-       return &ptrTypeStruct{ commonType{PtrKind, typestring, name, ptrsize}, sub}
+// Uint32Type represents a uint32 type.
+type Uint32Type struct {
+       commonType
 }
 
-func (t *ptrTypeStruct) FieldAlign() int {
-       return unsafe.Alignof(x.xptr);
+// Uint64Type represents a uint64 type.
+type Uint64Type struct {
+       commonType
 }
 
-func (t *ptrTypeStruct) Sub() Type {
-       return t.sub.Get()
+// Uint8Type represents a uint8 type.
+type Uint8Type struct {
+       commonType
 }
 
-// -- Array
-
-// ArrayType represents an array or slice type.
-type ArrayType interface {
-       Type;
-       IsSlice()       bool;   // True for slices, false for arrays.
-       Len()   int;    // 0 for slices, the length for array types.
-       Elem()  Type;   // The type of the elements.
+// UintType represents a uint type.
+type UintType struct {
+       commonType
 }
 
-type arrayTypeStruct struct {
-       commonType;
-       elem    *stubType;
-       isslice bool;   // otherwise fixed array
-       len     int;
+// StringType represents a string type.
+type StringType struct {
+       commonType
 }
 
-func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubType) *arrayTypeStruct {
-       return &arrayTypeStruct{ commonType{ArrayKind, typestring, name, 0 }, elem, open, len}
+// UintptrType represents a uintptr type.
+type UintptrType struct {
+       commonType
 }
 
-func (t *arrayTypeStruct) Size() int {
-       if t.isslice {
-               return unsafe.Sizeof(x.xslice);
-       }
-       return t.len * t.elem.Get().Size();
-}
-
-func (t *arrayTypeStruct) FieldAlign() int {
-        if t.isslice {
-               return unsafe.Alignof(x.xslice);
-       }
-       return t.elem.Get().FieldAlign();
+// DotDotDotType represents the ... that can
+// be used as the type of the final function parameter.
+type DotDotDotType struct {
+       commonType
 }
 
-func (t *arrayTypeStruct) IsSlice() bool {
-       return t.isslice
+// UnsafePointerType represents an unsafe.Pointer type.
+type UnsafePointerType struct {
+       commonType
 }
 
-func (t *arrayTypeStruct) Len() int {
-       if t.isslice {
-               return 0
-       }
-       return t.len
-}
-
-func (t *arrayTypeStruct) Elem() Type {
-       return t.elem.Get()
+// ArrayType represents a fixed array type.
+type ArrayType struct {
+       commonType;
+       elem *runtime.Type;
+       len uintptr;
 }
 
-// -- Map
-
-// MapType represents a map type.
-type MapType interface {
-       Type;
-       Key()   Type;   // The type of the keys.
-       Elem()  Type;   // The type of the elements/values.
-}
+// ChanDir represents a channel type's direction.
+type ChanDir int
+const (
+       RecvDir ChanDir = 1<<iota;
+       SendDir;
+       BothDir = RecvDir | SendDir;
+)
 
-type mapTypeStruct struct {
+// ChanType represents a channel type.
+type ChanType struct {
        commonType;
-       key     *stubType;
-       elem    *stubType;
+       elem *runtime.Type;
+       dir uintptr;
 }
 
-func newMapTypeStruct(name, typestring string, key, elem *stubType) *mapTypeStruct {
-       return &mapTypeStruct{ commonType{MapKind, typestring, name, ptrsize}, key, elem}
+// FuncType represents a function type.
+type FuncType struct {
+       commonType;
+       in []*runtime.Type;
+       out []*runtime.Type;
 }
 
-func (t *mapTypeStruct) FieldAlign() int {
-       return unsafe.Alignof(x.xmap);
+// Method on interface type
+type imethod struct {
+       hash uint32;
+       perm uint32;
+       name *string;
+       pkgPath *string;
+       typ *runtime.Type;
 }
 
-func (t *mapTypeStruct) Key() Type {
-       return t.key.Get()
+// InterfaceType represents an interface type.
+type InterfaceType struct {
+       commonType;
+       methods []imethod;
 }
 
-func (t *mapTypeStruct) Elem() Type {
-       return t.elem.Get()
+// MapType represents a map type.
+type MapType struct {
+       commonType;
+       key *runtime.Type;
+       elem *runtime.Type;
 }
 
-// -- Chan
-
-// ChanType represents a chan type.
-type ChanType interface {
-       Type;
-       Dir()   int;    // The direction of the channel.
-       Elem()  Type;   // The type of the elements.
+// PtrType represents a pointer type.
+type PtrType struct {
+       commonType;
+       elem *runtime.Type;
 }
 
-// Channel direction.
-const (
-       SendDir = 1 << iota;
-       RecvDir;
-       BothDir = SendDir | RecvDir;
-)
-
-type chanTypeStruct struct {
+// SliceType represents a slice type.
+type SliceType struct {
        commonType;
-       elem    *stubType;
-       dir     int;
+       elem *runtime.Type;
 }
 
-func newChanTypeStruct(name, typestring string, dir int, elem *stubType) *chanTypeStruct {
-       return &chanTypeStruct{ commonType{ChanKind, typestring, name, ptrsize}, elem, dir}
+// Struct field
+type structField struct {
+       name *string;
+       pkgPath *string;
+       typ *runtime.Type;
+       tag *string;
+       offset uintptr;
 }
 
-func (t *chanTypeStruct) FieldAlign() int {
-       return unsafe.Alignof(x.xchan);
+// StructType represents a struct type.
+type StructType struct {
+       commonType;
+       fields []structField;
 }
 
-func (t *chanTypeStruct) Dir() int {
-       return t.dir
-}
 
-func (t *chanTypeStruct) Elem() Type {
-       return t.elem.Get()
-}
+/*
+ * The compiler knows the exact layout of all the data structures above.
+ * The compiler does not know about the data structures and methods below.
+ */
 
-// -- Struct
+type Type interface
+type addr unsafe.Pointer
+type FuncValue struct
+func newFuncValue(typ Type, addr addr) *FuncValue
+
+// Method represents a single method.
+type Method struct {
+       PkgPath string;         // empty for uppercase Name
+       Name string;
+       Type *FuncType;
+       Func *FuncValue;
+}
+
+// Type is the runtime representation of a Go type.
+// Every type implements the methods listed here.
+// Some types implement additional interfaces;
+// use a type switch to find out what kind of type a Type is.
+// Each type in a program has a unique Type, so == on Types
+// corresponds to Go's type equality.
+type Type interface {
+       // Name returns the type's package and name.
+       // The package is a full package import path like "container/vector".
+       Name()  (pkgPath string, name string);
+
+       // String returns a string representation of the type.
+       // The string representation may use shortened package names
+       // (e.g., vector instead of "container/vector") and is not
+       // guaranteed to be unique among types.  To test for equality,
+       // compare the Types directly.
+       String()        string;
 
-// StructType represents a struct type.
-type StructType interface {
-       Type;
-       // Field returns, for field i, its name, Type, tag information, and byte offset.
-       // The indices are in declaration order starting at 0.
-       Field(i int)    (name string, typ Type, tag string, offset int);
-       // Len is the number of fields.
-       Len()   int;
-}
+       // Size returns the number of bytes needed to store
+       // a value of the given type; it is analogous to unsafe.Sizeof.
+       Size()  uintptr;
 
-type structField struct {
-       name    string;
-       typ     *stubType;
-       tag     string;
-       offset  int;
-}
+       // Align returns the alignment of a value of this type
+       // when allocated in memory.
+       Align() int;
 
-type structTypeStruct struct {
-       commonType;
-       field   []structField;
-       fieldAlign      int;
-}
+       // FieldAlign returns the alignment of a value of this type
+       // when used as a field in a struct.
+       FieldAlign()    int;
 
-func newStructTypeStruct(name, typestring string, field []structField) *structTypeStruct {
-       return &structTypeStruct{ commonType{StructKind, typestring, name, 0}, field, 0}
+       // For non-interface types, Method returns the i'th method with receiver T.
+       // For interface types, Method returns the i'th method in the interface.
+       // NumMethod returns the number of such methods.
+       Method(int)     Method;
+       NumMethod()     int;
 }
 
-func (t *structTypeStruct) FieldAlign() int {
-       t.Size();       // Compute size and alignment.
-       return t.fieldAlign
-}
+func toType(i interface{}) Type
 
-func (t *structTypeStruct) Size() int {
-       if t.size > 0 {
-               return t.size
+func (t *uncommonType) Name() (pkgPath string, name string) {
+       if t == nil {
+               return;
        }
-       size := 0;
-       structAlignMask := 0;
-       for i := 0; i < len(t.field); i++ {
-               typ := t.field[i].typ.Get();
-               elemsize := typ.Size();
-               alignMask := typ.FieldAlign() - 1;
-               if alignMask > structAlignMask {
-                       structAlignMask = alignMask
-               }
-               if alignMask > 0 {
-                       size = (size + alignMask) &^ alignMask;
-               }
-               t.field[i].offset = size;
-               size += elemsize;
+       if t.pkgPath != nil {
+               pkgPath = *t.pkgPath;
        }
-       if structAlignMask > 0 {
-               // 6g etc. always aligns structs to a minimum size, typically int64
-               if structAlignMask < minStructAlignMask {
-                       structAlignMask = minStructAlignMask
-               }
-               // TODO: In the PPC64 ELF ABI, floating point fields
-               // in a struct are aligned to a 4-byte boundary, but
-               // if the first field in the struct is a 64-bit float,
-               // the whole struct is aligned to an 8-byte boundary.
-               size = (size + structAlignMask) &^ structAlignMask;
-               t.fieldAlign = structAlignMask + 1;
+       if t.name != nil {
+               name = *t.name;
        }
-       t.size = size;
-       return size;
+       return;
 }
 
-func (t *structTypeStruct) Field(i int) (name string, typ Type, tag string, offset int) {
-       if t.field[i].offset == 0 {
-               t.Size();       // will compute offsets
-       }
-       return t.field[i].name, t.field[i].typ.Get(), t.field[i].tag, t.field[i].offset
+func (t *commonType) String() string {
+       return *t.string;
 }
 
-func (t *structTypeStruct) Len() int {
-       return len(t.field)
+func (t *commonType) Size() uintptr {
+       return t.size;
 }
 
-// -- Interface
-
-// InterfaceType represents an interface type.
-// It behaves much like a StructType, treating the methods as fields.
-type InterfaceType interface {
-       Type;
-       // Field returns, for method i, its name, Type, the empty string, and 0.
-       // The indices are in declaration order starting at 0.  TODO: is this true?
-       Field(int)      (name string, typ Type, tag string, offset int);
-       Len()   int;
+func (t *commonType) Align() int {
+       return int(t.align);
 }
 
-type interfaceTypeStruct struct {
-       commonType;
-       field   []structField;
+func (t *commonType) FieldAlign() int {
+       return int(t.fieldAlign);
 }
 
-func newInterfaceTypeStruct(name, typestring string, field []structField) *interfaceTypeStruct {
-       return &interfaceTypeStruct{ commonType{InterfaceKind, typestring, name, interfacesize}, field }
+func (t *uncommonType) Method(i int) (m Method) {
+       if t == nil || i < 0 || i >= len(t.methods) {
+               return;
+       }
+       p := &t.methods[i];
+       if p.name != nil {
+               m.Name = *p.name;
+       }
+       if p.pkgPath != nil {
+               m.PkgPath = *p.pkgPath;
+       }
+       m.Type = toType(*p.typ).(*FuncType);
+       fn := p.tfn;
+       m.Func = newFuncValue(m.Type, addr(&fn));
+       return;
 }
 
-func (t *interfaceTypeStruct) FieldAlign() int {
-       return unsafe.Alignof(x.xinterface);
+func (t *uncommonType) NumMethod() int {
+       if t == nil {
+               return 0;
+       }
+       return len(t.methods);
 }
 
-func (t *interfaceTypeStruct) Field(i int) (name string, typ Type, tag string, offset int) {
-       return t.field[i].name, t.field[i].typ.Get(), "", 0
+// TODO(rsc): 6g supplies these, but they are not
+// as efficient as they could be: they have commonType
+// as the receiver instead of *commonType.
+func (t *commonType) NumMethod() int {
+       return t.uncommonType.NumMethod();
 }
 
-func (t *interfaceTypeStruct) Len() int {
-       return len(t.field)
+func (t *commonType) Method(i int) (m Method) {
+       return t.uncommonType.Method(i);
 }
 
-var nilInterface = newInterfaceTypeStruct("nil", "", make([]structField, 0));
-
-// -- Func
-
-// FuncType represents a function type.
-type FuncType interface {
-       Type;
-       In()    StructType;     // The parameters in the form of a StructType.
-       Out()   StructType;     // The results in the form of a StructType.
+func (t *commonType) Name() (pkgPath string, name string) {
+       return t.uncommonType.Name();
 }
 
-type funcTypeStruct struct {
-       commonType;
-       in      *structTypeStruct;
-       out     *structTypeStruct;
+// Len returns the number of elements in the array.
+func (t *ArrayType) Len() int {
+       return int(t.len);
 }
 
-func newFuncTypeStruct(name, typestring string, in, out *structTypeStruct) *funcTypeStruct {
-       return &funcTypeStruct{ commonType{FuncKind, typestring, name, ptrsize}, in, out }
+// Elem returns the type of the array's elements.
+func (t *ArrayType) Elem() Type {
+       return toType(*t.elem);
 }
 
-func (t *funcTypeStruct) FieldAlign() int {
-       return unsafe.Alignof(x.xfunc);
+// Dir returns the channel direction.
+func (t *ChanType) Dir() ChanDir {
+       return ChanDir(t.dir);
 }
 
-func (t *funcTypeStruct) In() StructType {
-       return t.in
+// Elem returns the channel's element type.
+func (t *ChanType) Elem() Type {
+       return toType(*t.elem);
 }
 
-func (t *funcTypeStruct) Out() StructType {
-       if t.out == nil {       // nil.(StructType) != nil so make sure caller sees real nil
-               return nil
+func (d ChanDir) String() string {
+       switch d {
+       case SendDir:
+               return "chan<-";
+       case RecvDir:
+               return "<-chan";
+       case BothDir:
+               return "chan";
        }
-       return t.out
+       return "ChanDir" + strconv.Itoa(int(d));
 }
 
-// Cache of expanded types keyed by type name.
-var types map[string] Type
-
-// List of typename, typestring pairs
-var typestring map[string] string
-var initialized bool = false
-
-// Map of basic types to prebuilt stubTypes
-var basicstub map[string] *stubType
-
-var missingStub *stubType;
-var dotDotDotStub *stubType;
-
-// The database stored in the maps is global; use locking to guarantee safety.
-var typestringlock sync.Mutex
-
-func lock() {
-       typestringlock.Lock()
-}
-
-func unlock() {
-       typestringlock.Unlock()
-}
-
-func init() {
-       lock(); // not necessary because of init ordering but be safe.
-
-       types = make(map[string] Type);
-       typestring = make(map[string] string);
-       basicstub = make(map[string] *stubType);
-
-       // Basics go into types table
-       types[missingString] = Missing;
-       types[dotDotDotString] = DotDotDot;
-       types["int"] = Int;
-       types["int8"] = Int8;
-       types["int16"] = Int16;
-       types["int32"] = Int32;
-       types["int64"] = Int64;
-       types["uint"] = Uint;
-       types["uint8"] = Uint8;
-       types["uint16"] = Uint16;
-       types["uint32"] = Uint32;
-       types["uint64"] = Uint64;
-       types["uintptr"] = Uintptr;
-       types["float"] = Float;
-       types["float32"] = Float32;
-       types["float64"] = Float64;
-       types["string"] = String;
-       types["bool"] = Bool;
-
-       // Basics get prebuilt stubs
-       missingStub = newStubType(missingString, Missing);
-       dotDotDotStub = newStubType(dotDotDotString, DotDotDot);
-       basicstub[missingString] = missingStub;
-       basicstub[dotDotDotString] = dotDotDotStub;
-       basicstub["int"] = newStubType("int", Int);
-       basicstub["int8"] = newStubType("int8", Int8);
-       basicstub["int16"] = newStubType("int16", Int16);
-       basicstub["int32"] = newStubType("int32", Int32);
-       basicstub["int64"] = newStubType("int64", Int64);
-       basicstub["uint"] = newStubType("uint", Uint);
-       basicstub["uint8"] = newStubType("uint8", Uint8);
-       basicstub["uint16"] = newStubType("uint16", Uint16);
-       basicstub["uint32"] = newStubType("uint32", Uint32);
-       basicstub["uint64"] = newStubType("uint64", Uint64);
-       basicstub["uintptr"] = newStubType("uintptr", Uintptr);
-       basicstub["float"] = newStubType("float", Float);
-       basicstub["float32"] = newStubType("float32", Float32);
-       basicstub["float64"] = newStubType("float64", Float64);
-       basicstub["string"] = newStubType("string", String);
-       basicstub["bool"] = newStubType("bool", Bool);
-
-       unlock();
-}
-
-/*
-       Parsing of type strings.  These strings are how the run-time recovers type
-       information dynamically.
-
-       Grammar
-
-       stubtype =      - represent as StubType when possible
-               type
-       identifier =
-               name
-               '?'
-       type =
-               basictypename   - int8, string, etc.
-               typename
-               arraytype
-               structtype
-               interfacetype
-               chantype
-               maptype
-               pointertype
-               functiontype
-       typename =
-               name '.' name
-       doublequotedstring =
-               string in " ";  escapes are \x00 (NUL) \n \t \" \\
-       fieldlist =
-               [ field { [ ',' | ';' ] field } ]
-       field =
-               identifier stubtype [ doublequotedstring ]
-       arraytype =
-               '[' [ number ] ']' stubtype
-       structtype =
-               'struct' '{' fieldlist '}'
-       interfacetype =
-               'interface' '{' fieldlist '}'
-       chantype =
-               '<-' 'chan' stubtype
-               'chan' '<-' stubtype
-               'chan' stubtype
-       maptype =
-               'map' '[' stubtype ']' stubtype
-       pointertype =
-               '*' stubtype
-       functiontype =
-               [ 'func' ] '(' fieldlist ')' [ '(' fieldlist ')' | stubtype ]
-
-       In functiontype 'func' is optional because it is omitted in
-       the reflection string for interface types.
-
-*/
-
-// Helper functions for token scanning
-func isdigit(c uint8) bool {
-       return '0' <= c && c <= '9'
-}
-
-func special(c uint8) bool {
-       s := "*[](){}<;,";      // Note: '.' is not in this list.  "P.T" is an identifer, as is "?".
-       for i := 0; i < len(s); i++ {
-               if c == s[i] {
-                       return true
-               }
+// In returns the type of the i'th function input parameter.
+func (t *FuncType) In(i int) Type {
+       if i < 0 || i >= len(t.in) {
+               return nil;
        }
-       return false;
+       return toType(*t.in[i]);
 }
 
-func hex00(s string, i int) bool {
-       return i + 2 < len(s) && s[i] == '0' && s[i+1] == '0'
+// NumIn returns the number of input parameters.
+func (t *FuncType) NumIn() int {
+       return len(t.in);
 }
 
-// Process backslashes.  String known to be well-formed.
-// Initial double-quote is left in, as an indication this token is a string.
-func unescape(s string, backslash bool) string {
-       if !backslash {
-               return s
-       }
-       out := "\"";
-       for i := 1; i < len(s); i++ {
-               c := s[i];
-               if c == '\\' {
-                       i++;
-                       c = s[i];
-                       switch c {
-                       case 'n':
-                               c = '\n';
-                       case 't':
-                               c = '\t';
-                       case 'x':
-                               if hex00(s, i+1) {
-                                       i += 2;
-                                       c = 0;
-                                       break;
-                               }
-                       // otherwise just put an 'x'; erroneous but safe.
-                       // default is correct already; \\ is \; \" is "
-                       }
-               }
-               out += string(c);
+// Out returns the type of the i'th function output parameter.
+func (t *FuncType) Out(i int) Type {
+       if i < 0 || i >= len(t.out) {
+               return nil;
        }
-       return out;
-}
-
-// Simple parser for type strings
-type typeParser struct {
-       str     string; // string being parsed
-       token   string; // the token being parsed now
-       tokstart        int;    // starting position of token
-       prevend int;    // (one after) ending position of previous token
-       index   int;    // next character position in str
+       return toType(*t.out[i]);
 }
 
-// Return typestring starting at position i.  It will finish at the
-// end of the previous token (before trailing white space).
-func (p *typeParser) TypeString(i int) string {
-       return p.str[i:p.prevend];
+// NumOut returns the number of function output parameters.
+func (t *FuncType) NumOut() int {
+       return len(t.out);
 }
 
-// Load next token into p.token
-func (p *typeParser) Next() {
-       p.prevend = p.index;
-       token := "";
-       for ; p.index < len(p.str) && p.str[p.index] == ' '; p.index++ {
-       }
-       p.tokstart = p.index;
-       if p.index >= len(p.str) {
-               p.token = "";
-               return;
-       }
-       start := p.index;
-       c, w := utf8.DecodeRuneInString(p.str[p.index:len(p.str)]);
-       p.index += w;
-       switch {
-       case c == '<':
-               if p.index < len(p.str) && p.str[p.index] == '-' {
-                       p.index++;
-                       p.token = "<-";
-                       return;
-               }
-               fallthrough;    // shouldn't happen but let the parser figure it out
-       case c == '.':
-               if p.index < len(p.str)+2 && p.str[p.index-1:p.index+2] == dotDotDotString {
-                       p.index += 2;
-                       p.token = dotDotDotString;
-                       return;
-               }
-               fallthrough;    // shouldn't happen but let the parser figure it out
-       case special(uint8(c)):
-               p.token = string(c);
-               return;
-       case isdigit(uint8(c)):
-               for p.index < len(p.str) && isdigit(p.str[p.index]) {
-                       p.index++
-               }
-               p.token = p.str[start : p.index];
-               return;
-       case c == '"':  // double-quoted string for struct field annotation
-               backslash := false;
-               for p.index < len(p.str) && p.str[p.index] != '"' {
-                       if p.str[p.index] == '\\' {
-                               if p.index+1 == len(p.str) {    // bad final backslash
-                                       break;
-                               }
-                               p.index++;      // skip (and accept) backslash
-                               backslash = true;
-                       }
-                       p.index++
-               }
-               p.token = unescape(p.str[start : p.index], backslash);
-               if p.index < len(p.str) {       // properly terminated string
-                       p.index++;      // skip the terminating double-quote
-               }
+// Method returns the i'th interface method.
+func (t *InterfaceType) Method(i int) (m Method) {
+       if i < 0 || i >= len(t.methods) {
                return;
        }
-       for p.index < len(p.str) && p.str[p.index] != ' ' && !special(p.str[p.index]) {
-               p.index++
+       p := t.methods[i];
+       m.Name = *p.name;
+       if p.pkgPath != nil {
+               m.PkgPath = *p.pkgPath;
        }
-       p.token = p.str[start : p.index];
+       m.Type = toType(*p.typ).(*FuncType);
+       return;
 }
 
-func (p *typeParser) Type(name string) *stubType
-
-func (p *typeParser) Array(name string, tokstart int) *stubType {
-       size := 0;
-       open := true;
-       if p.token != "]" {
-               if len(p.token) == 0 || !isdigit(p.token[0]) {
-                       return missingStub
-               }
-               // write our own (trivial and simpleminded) atoi to avoid dependency
-               size = 0;
-               for i := 0; i < len(p.token); i++ {
-                       size = size * 10 + int(p.token[i]) - '0'
-               }
-               p.Next();
-               open = false;
-       }
-       if p.token != "]" {
-               return missingStub
-       }
-       p.Next();
-       elemtype := p.Type("");
-       return newStubType(name, newArrayTypeStruct(name, p.TypeString(tokstart), open, size, elemtype));
+// NumMethod returns the number of interface methods.
+func (t *InterfaceType) NumMethod() int {
+       return len(t.methods);
 }
 
-func (p *typeParser) Map(name string, tokstart int) *stubType {
-       if p.token != "[" {
-               return missingStub
-       }
-       p.Next();
-       keytype := p.Type("");
-       if p.token != "]" {
-               return missingStub
-       }
-       p.Next();
-       elemtype := p.Type("");
-       return newStubType(name, newMapTypeStruct(name, p.TypeString(tokstart), keytype, elemtype));
+// Key returns the map key type.
+func (t *MapType) Key() Type {
+       return toType(*t.key);
 }
 
-func (p *typeParser) Chan(name string, tokstart, dir int) *stubType {
-       if p.token == "<-" {
-               if dir != BothDir {
-                       return missingStub
-               }
-               p.Next();
-               dir = SendDir;
-       }
-       elemtype := p.Type("");
-       return newStubType(name, newChanTypeStruct(name, p.TypeString(tokstart), dir, elemtype));
+// Elem returns the map element type.
+func (t *MapType) Elem() Type {
+       return toType(*t.elem);
 }
 
-// Parse array of fields for struct, interface, and func arguments
-func (p *typeParser) Fields(sep, term string) []structField {
-       a := make([]structField, 10);
-       nf := 0;
-       for p.token != "" && p.token != term {
-               if nf == len(a) {
-                       a1 := make([]structField, 2*nf);
-                       for i := 0; i < nf; i++ {
-                               a1[i] = a[i];
-                       }
-                       a = a1;
-               }
-               name := p.token;
-               if name == "?" {        // used to represent a missing name
-                       name = ""
-               }
-               a[nf].name = name;
-               p.Next();
-               a[nf].typ = p.Type("");
-               if p.token != "" && p.token[0] == '"' {
-                       a[nf].tag = p.token[1:len(p.token)];
-                       p.Next();
-               }
-               nf++;
-               if p.token != sep {
-                       break;
-               }
-               p.Next();       // skip separator
-       }
-       return a[0:nf];
+// Elem returns the pointer element type.
+func (t *PtrType) Elem() Type {
+       return toType(*t.elem);
 }
 
-// A single type packaged as a field for a function return
-func (p *typeParser) OneField() []structField {
-       a := make([]structField, 1);
-       a[0].name = "";
-       a[0].typ = p.Type("");
-       return a;
+// Elem returns the type of the slice's elements.
+func (t *SliceType) Elem() Type {
+       return toType(*t.elem);
 }
 
-func (p *typeParser) Struct(name string, tokstart int) *stubType {
-       f := p.Fields(";", "}");
-       if p.token != "}" {
-               return missingStub;
-       }
-       p.Next();
-       return newStubType(name, newStructTypeStruct(name, p.TypeString(tokstart), f));
-}
-
-func (p *typeParser) Interface(name string, tokstart int) *stubType {
-       f := p.Fields(";", "}");
-       if p.token != "}" {
-               return missingStub;
-       }
-       p.Next();
-       return newStubType(name, newInterfaceTypeStruct(name, p.TypeString(tokstart), f));
+type StructField struct {
+       PkgPath string;         // empty for uppercase Name
+       Name string;
+       Type Type;
+       Tag string;
+       Offset uintptr;
+       Anonymous bool;
 }
 
-func (p *typeParser) Func(name string, tokstart int) *stubType {
-       // may be 1 or 2 parenthesized lists
-       f1 := newStructTypeStruct("", "", p.Fields(",", ")"));
-       if p.token != ")" {
-               return missingStub;
+// Field returns the i'th struct field.
+func (t *StructType) Field(i int) (f StructField) {
+       if i < 0 || i >= len(t.fields) {
+               return;
        }
-       p.Next();
-       if p.token != "(" {
-               // 1 list: the in parameters are a list.  Is there a single out parameter?
-               switch p.token {
-               case "", "}", ")", ",", ";":
-                       return newStubType(name, newFuncTypeStruct(name, p.TypeString(tokstart), f1, nil));
-               }
-               // A single out parameter.
-               f2 := newStructTypeStruct("", "", p.OneField());
-               return newStubType(name, newFuncTypeStruct(name, p.TypeString(tokstart), f1, f2));
+       p := t.fields[i];
+       f.Type = toType(*p.typ);
+       if p.name != nil {
+               f.Name = *p.name;
        } else {
-               p.Next();
-       }
-       f2 := newStructTypeStruct("", "", p.Fields(",", ")"));
-       if p.token != ")" {
-               return missingStub;
-       }
-       p.Next();
-       // 2 lists: the in and out parameters are present
-       return newStubType(name, newFuncTypeStruct(name, p.TypeString(tokstart), f1, f2));
-}
-
-func (p *typeParser) Type(name string) *stubType {
-       dir := BothDir;
-       tokstart := p.tokstart;
-       switch {
-       case p.token == "":
-               return nil;
-       case p.token == "*":
-               p.Next();
-               sub := p.Type("");
-               return newStubType(name, newPtrTypeStruct(name, p.TypeString(tokstart), sub));
-       case p.token == "[":
-               p.Next();
-               return p.Array(name, tokstart);
-       case p.token == "map":
-               p.Next();
-               return p.Map(name, tokstart);
-       case p.token == "<-":
-               p.Next();
-               dir = RecvDir;
-               if p.token != "chan" {
-                       return missingStub;
-               }
-               fallthrough;
-       case p.token == "chan":
-               p.Next();
-               return p.Chan(name, tokstart, dir);
-       case p.token == "struct":
-               p.Next();
-               if p.token != "{" {
-                       return missingStub
-               }
-               p.Next();
-               return p.Struct(name, tokstart);
-       case p.token == "interface":
-               p.Next();
-               if p.token != "{" {
-                       return missingStub
-               }
-               p.Next();
-               return p.Interface(name, tokstart);
-       case p.token == "func":
-               p.Next();
-               if p.token != "(" {
-                       return missingStub
-               }
-               p.Next();
-               return p.Func(name, tokstart);
-       case p.token == "(":
-               p.Next();
-               return p.Func(name, tokstart);
-       case isdigit(p.token[0]):
-               p.Next();
-               return missingStub;
-       case special(p.token[0]):
-               p.Next();
-               return missingStub;
-       }
-       // must be an identifier. is it basic? if so, we have a stub
-       if s, ok := basicstub[p.token]; ok {
-               p.Next();
-               if name != "" {
-                       // Need to make a copy because we are renaming a basic type
-                       b := s.Get();
-                       s = newStubType(name, newBasicType(name, b.Kind(), b.Size(), b.FieldAlign()));
-               }
-               return s
-       }
-       // not a basic - must be of the form "P.T"
-       ndot := 0;
-       for i := 0; i < len(p.token); i++ {
-               if p.token[i] == '.' {
-                       ndot++
-               }
-       }
-       if ndot != 1 {
-               p.Next();
-               return missingStub;
-       }
-       s := newStubType(p.token, nil);
-       p.Next();
-       return s;
-}
-
-// ParseTypeString takes a type name and type string (such as "[]int") and
-// returns the Type structure representing a type name specifying the corresponding
-// type.  An empty typestring represents (the type of) a nil interface value.
-func ParseTypeString(name, typestring string) Type {
-       if typestring == "" {
-               // If the typestring is empty, it represents (the type of) a nil interface value
-               return nilInterface
-       }
-       p := new(typeParser);
-       p.str = typestring;
-       p.Next();
-       return p.Type(name).Get();
+               nam, pkg := f.Type.Name();
+               f.Name = nam;
+               f.Anonymous = true;
+       }
+       if p.pkgPath != nil {
+               f.PkgPath = *p.pkgPath;
+       }
+       if p.tag != nil {
+               f.Tag = *p.tag;
+       }
+       f.Offset = p.offset;
+       return;
+}
+
+// NumField returns the number of struct fields.
+func (t *StructType) NumField() int {
+       return len(t.fields);
+}
+
+// Convert runtime type to reflect type.
+// Same memory layouts, different method sets.
+func toType(i interface{}) Type {
+       switch v := i.(type) {
+       case *runtime.BoolType:
+               return (*BoolType)(unsafe.Pointer(v));
+       case *runtime.DotDotDotType:
+               return (*DotDotDotType)(unsafe.Pointer(v));
+       case *runtime.FloatType:
+               return (*FloatType)(unsafe.Pointer(v));
+       case *runtime.Float32Type:
+               return (*Float32Type)(unsafe.Pointer(v));
+       case *runtime.Float64Type:
+               return (*Float64Type)(unsafe.Pointer(v));
+       case *runtime.IntType:
+               return (*IntType)(unsafe.Pointer(v));
+       case *runtime.Int8Type:
+               return (*Int8Type)(unsafe.Pointer(v));
+       case *runtime.Int16Type:
+               return (*Int16Type)(unsafe.Pointer(v));
+       case *runtime.Int32Type:
+               return (*Int32Type)(unsafe.Pointer(v));
+       case *runtime.Int64Type:
+               return (*Int64Type)(unsafe.Pointer(v));
+       case *runtime.StringType:
+               return (*StringType)(unsafe.Pointer(v));
+       case *runtime.UintType:
+               return (*UintType)(unsafe.Pointer(v));
+       case *runtime.Uint8Type:
+               return (*Uint8Type)(unsafe.Pointer(v));
+       case *runtime.Uint16Type:
+               return (*Uint16Type)(unsafe.Pointer(v));
+       case *runtime.Uint32Type:
+               return (*Uint32Type)(unsafe.Pointer(v));
+       case *runtime.Uint64Type:
+               return (*Uint64Type)(unsafe.Pointer(v));
+       case *runtime.UintptrType:
+               return (*UintptrType)(unsafe.Pointer(v));
+       case *runtime.UnsafePointerType:
+               return (*UnsafePointerType)(unsafe.Pointer(v));
+       case *runtime.ArrayType:
+               return (*ArrayType)(unsafe.Pointer(v));
+       case *runtime.ChanType:
+               return (*ChanType)(unsafe.Pointer(v));
+       case *runtime.FuncType:
+               return (*FuncType)(unsafe.Pointer(v));
+       case *runtime.InterfaceType:
+               return (*InterfaceType)(unsafe.Pointer(v));
+       case *runtime.MapType:
+               return (*MapType)(unsafe.Pointer(v));
+       case *runtime.PtrType:
+               return (*PtrType)(unsafe.Pointer(v));
+       case *runtime.SliceType:
+               return (*SliceType)(unsafe.Pointer(v));
+       case *runtime.StructType:
+               return (*StructType)(unsafe.Pointer(v));
+       }
+       panicln("toType", i);
+}
+
+// ArrayOrSliceType is the common interface implemented
+// by both ArrayType and SliceType.
+type ArrayOrSliceType interface {
+       Type;
+       Elem() Type;
 }
 
-// Create typestring map from reflect.typestrings() data.  Lock is held.
-func initializeTypeStrings() {
-       if initialized {
-               return
-       }
-       initialized = true;
-       s := typestrings();
-       slen := len(s);
-       for i := 0; i < slen; {
-               // "reflect.PtrType interface { Sub () (? reflect.Type) }\n"
-               // find the identifier
-               idstart := i;
-               for ; i < slen && s[i] != ' '; i++ {
-               }
-               if i == slen {
-                       print("reflect.InitializeTypeStrings: bad identifier\n");
-                       return;
-               }
-               idend := i;
-               i++;
-               // find the end of the line, terminating the type
-               typestart := i;
-               for ; i < slen && s[i] != '\n'; i++ {
-               }
-               if i == slen {
-                       print("reflect.InitializeTypeStrings: bad type string\n");
-                       return;
-               }
-               typeend := i;
-               i++;    //skip newline
-               typestring[s[idstart:idend]] = s[typestart:typeend];
-       }
-}
 
-// Look up type string associated with name.  Lock is held.
-func typeNameToTypeString(name string) string {
-       s, ok := typestring[name];
-       if !ok {
-               initializeTypeStrings();
-               s, ok = typestring[name];
-               if !ok {
-                       s = missingString;
-                       typestring[name] = s;
-               }
-       }
-       return s
-}
-
-// ExpandType takes the name of a type and returns its Type structure,
-// unpacking the associated type string if necessary.
-func ExpandType(name string) Type {
-       lock();
-       t, ok := types[name];
-       if ok {
-               unlock();
-               return t
-       }
-       types[name] = Missing;  // prevent recursion; will overwrite
-       t1 := ParseTypeString(name, typeNameToTypeString(name));
-       types[name] = t1;
-       unlock();
-       return t1;
-}
index 26ba6cb6b493df126a8cbbab0140f31af138840f..69e1eb3c41800ee028c4ff7a48cbe44bedab98f3 100644 (file)
@@ -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 @@ import (
        "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()
+// 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 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));
+               }
+       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));
+               }
+       }
 }
 
-// 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.
+// Value is the common interface to reflection values.
+// The implementations of Value (e.g., ArrayValue, StructValue)
+// have additional type-specific methods.
 type Value interface {
-       // The kind of thing described: ArrayKind, BoolKind, etc.
-       Kind()  int;
-       // The reflection Type of the value.
+       // Type returns the value's type.
        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;
+       // Interface returns the value as an interface{}.
+       Interface()     interface{};
 
-// commonValue fields and functionality for all values
+       // 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;
 
-type commonValue struct {
-       kind    int;
-       typ     Type;
-       addr    Addr;
+       // Addr returns a pointer to the underlying data.
+       // It is for advanced clients that also
+       // import the "unsafe" package.
+       Addr()  uintptr;
 }
 
-func (c *commonValue) Kind() int {
-       return c.kind
+type value struct {
+       typ Type;
+       addr addr;
+       canSet bool;
 }
 
-func (c *commonValue) Type() Type {
-       return c.typ
+func (v *value) Type() Type {
+       return v.typ
 }
 
-func (c *commonValue) Addr() Addr {
-       return c.addr
+func (v *value) Addr() uintptr {
+       return uintptr(v.addr);
 }
 
-func (c *commonValue) Interface() interface {} {
-       var i interface {};
-       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());
+type InterfaceValue struct
+type StructValue struct
+
+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)
                }
-               i = unsafe.Unreflect(uint64(uintptr(*(*Addr)(c.addr))), c.typ.String(), false);
+               // Extract from v.addr as interface value with methods.
+               return *(*interface{ m() })(v.addr)
        }
-       return i;
+       return unsafe.Unreflect(v.typ, unsafe.Pointer(v.addr));
 }
 
-func newValueAddr(typ Type, addr Addr) Value
-
-type creatorFn func(typ Type, addr Addr) Value
+func (v *value) CanSet() bool {
+       return v.canSet;
+}
 
+func newValue(typ Type, addr addr, canSet bool) Value
+func NewValue(i interface{}) Value
 
-// -- Missing
+/*
+ * basic types
+ */
 
-// MissingValue represents a value whose type is not known. It usually
-// indicates an error.
-type MissingValue interface {
-       Value;
+// BoolValue represents a bool value.
+type BoolValue struct {
+       value;
 }
 
-type missingValueStruct struct {
-       commonValue
+// Get returns the underlying bool value.
+func (v *BoolValue) Get() bool {
+       return *(*bool)(v.addr);
 }
 
-func missingCreator(typ Type, addr Addr) Value {
-       return &missingValueStruct{ commonValue{MissingKind, typ, addr} }
+// Set sets v to the value x.
+func (v *BoolValue) Set(x bool) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*bool)(v.addr) = x;
 }
 
-// -- Int
-
-// IntValue represents an int value.
-type IntValue interface {
-       Value;
-       Get()   int;    // Get the underlying int.
-       Set(int);       // Set the underlying int.
+// FloatValue represents a float value.
+type FloatValue struct {
+       value;
 }
 
-type intValueStruct struct {
-       commonValue
+// Get returns the underlying float value.
+func (v *FloatValue) Get() float {
+       return *(*float)(v.addr);
 }
 
-func intCreator(typ Type, addr Addr) Value {
-       return &intValueStruct{ commonValue{IntKind, typ, addr} }
+// Set sets v to the value x.
+func (v *FloatValue) Set(x float) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*float)(v.addr) = x;
 }
 
-func (v *intValueStruct) Get() int {
-       return *(*int)(v.addr)
+// Float32Value represents a float32 value.
+type Float32Value struct {
+       value;
 }
 
-func (v *intValueStruct) Set(i int) {
-       *(*int)(v.addr) = i
+// Get returns the underlying float32 value.
+func (v *Float32Value) Get() float32 {
+       return *(*float32)(v.addr);
 }
 
-// -- Int8
-
-// Int8Value represents an int8 value.
-type Int8Value interface {
-       Value;
-       Get()   int8;   // Get the underlying int8.
-       Set(int8);      // Set the underlying int8.
+// Set sets v to the value x.
+func (v *Float32Value) Set(x float32) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*float32)(v.addr) = x;
 }
 
-type int8ValueStruct struct {
-       commonValue
+// Float64Value represents a float64 value.
+type Float64Value struct {
+       value;
 }
 
-func int8Creator(typ Type, addr Addr) Value {
-       return &int8ValueStruct{ commonValue{Int8Kind, typ, addr} }
+// Get returns the underlying float64 value.
+func (v *Float64Value) Get() float64 {
+       return *(*float64)(v.addr);
 }
 
-func (v *int8ValueStruct) Get() int8 {
-       return *(*int8)(v.addr)
+// Set sets v to the value x.
+func (v *Float64Value) Set(x float64) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*float64)(v.addr) = x;
 }
 
-func (v *int8ValueStruct) Set(i int8) {
-       *(*int8)(v.addr) = i
+// IntValue represents an int value.
+type IntValue struct {
+       value;
 }
 
-// -- Int16
-
-// Int16Value represents an int16 value.
-type Int16Value interface {
-       Value;
-       Get()   int16;  // Get the underlying int16.
-       Set(int16);     // Set the underlying int16.
+// Get returns the underlying int value.
+func (v *IntValue) Get() int {
+       return *(*int)(v.addr);
 }
 
-type int16ValueStruct struct {
-       commonValue
+// Set sets v to the value x.
+func (v *IntValue) Set(x int) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*int)(v.addr) = x;
 }
 
-func int16Creator(typ Type, addr Addr) Value {
-       return &int16ValueStruct{ commonValue{Int16Kind, typ, addr} }
+// Int8Value represents an int8 value.
+type Int8Value struct {
+       value;
 }
 
-func (v *int16ValueStruct) Get() int16 {
-       return *(*int16)(v.addr)
+// Get returns the underlying int8 value.
+func (v *Int8Value) Get() int8 {
+       return *(*int8)(v.addr);
 }
 
-func (v *int16ValueStruct) Set(i int16) {
-       *(*int16)(v.addr) = i
+// Set sets v to the value x.
+func (v *Int8Value) Set(x int8) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*int8)(v.addr) = x;
 }
 
-// -- Int32
-
-// Int32Value represents an int32 value.
-type Int32Value interface {
-       Value;
-       Get()   int32;  // Get the underlying int32.
-       Set(int32);     // Set the underlying int32.
+// Int16Value represents an int16 value.
+type Int16Value struct {
+       value;
 }
 
-type int32ValueStruct struct {
-       commonValue
+// Get returns the underlying int16 value.
+func (v *Int16Value) Get() int16 {
+       return *(*int16)(v.addr);
 }
 
-func int32Creator(typ Type, addr Addr) Value {
-       return &int32ValueStruct{ commonValue{Int32Kind, typ, addr} }
+// Set sets v to the value x.
+func (v *Int16Value) Set(x int16) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*int16)(v.addr) = x;
 }
 
-func (v *int32ValueStruct) Get() int32 {
-       return *(*int32)(v.addr)
+// Int32Value represents an int32 value.
+type Int32Value struct {
+       value;
 }
 
-func (v *int32ValueStruct) Set(i int32) {
-       *(*int32)(v.addr) = i
+// Get returns the underlying int32 value.
+func (v *Int32Value) Get() int32 {
+       return *(*int32)(v.addr);
 }
 
-// -- Int64
-
-// Int64Value represents an int64 value.
-type Int64Value interface {
-       Value;
-       Get()   int64;  // Get the underlying int64.
-       Set(int64);     // Set the underlying int64.
+// Set sets v to the value x.
+func (v *Int32Value) Set(x int32) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*int32)(v.addr) = x;
 }
 
-type int64ValueStruct struct {
-       commonValue
+// Int64Value represents an int64 value.
+type Int64Value struct {
+       value;
 }
 
-func int64Creator(typ Type, addr Addr) Value {
-       return &int64ValueStruct{ commonValue{Int64Kind, typ, addr} }
+// Get returns the underlying int64 value.
+func (v *Int64Value) Get() int64 {
+       return *(*int64)(v.addr);
 }
 
-func (v *int64ValueStruct) 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;
 }
 
-func (v *int64ValueStruct) Set(i int64) {
-       *(*int64)(v.addr) = i
+// StringValue represents a string value.
+type StringValue struct {
+       value;
 }
 
-// -- Uint
-
-// UintValue represents a uint value.
-type UintValue interface {
-       Value;
-       Get()   uint;   // Get the underlying uint.
-       Set(uint);      // Set the underlying uint.
+// Get returns the underlying string value.
+func (v *StringValue) Get() string {
+       return *(*string)(v.addr);
 }
 
-type uintValueStruct struct {
-       commonValue
+// Set sets v to the value x.
+func (v *StringValue) Set(x string) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*string)(v.addr) = x;
 }
 
-func uintCreator(typ Type, addr Addr) Value {
-       return &uintValueStruct{ commonValue{UintKind, typ, addr} }
+// UintValue represents a uint value.
+type UintValue struct {
+       value;
 }
 
-func (v *uintValueStruct) Get() uint {
-       return *(*uint)(v.addr)
+// Get returns the underlying uint value.
+func (v *UintValue) Get() uint {
+       return *(*uint)(v.addr);
 }
 
-func (v *uintValueStruct) Set(i uint) {
-       *(*uint)(v.addr) = i
+// Set sets v to the value x.
+func (v *UintValue) Set(x uint) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uint)(v.addr) = x;
 }
 
-// -- 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
+type Uint8Value struct {
+       value;
 }
 
-func uint8Creator(typ Type, addr Addr) Value {
-       return &uint8ValueStruct{ commonValue{Uint8Kind, typ, addr} }
+// Get returns the underlying uint8 value.
+func (v *Uint8Value) Get() uint8 {
+       return *(*uint8)(v.addr);
 }
 
-func (v *uint8ValueStruct) Get() uint8 {
-       return *(*uint8)(v.addr)
-}
-
-func (v *uint8ValueStruct) Set(i uint8) {
-       *(*uint8)(v.addr) = i
+// Set sets v to the value x.
+func (v *Uint8Value) Set(x uint8) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uint8)(v.addr) = x;
 }
 
-// -- 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
+type Uint16Value struct {
+       value;
 }
 
-func uint16Creator(typ Type, addr Addr) Value {
-       return &uint16ValueStruct{ commonValue{Uint16Kind, typ, addr} }
+// Get returns the underlying uint16 value.
+func (v *Uint16Value) Get() uint16 {
+       return *(*uint16)(v.addr);
 }
 
-func (v *uint16ValueStruct) Get() uint16 {
-       return *(*uint16)(v.addr)
-}
-
-func (v *uint16ValueStruct) Set(i uint16) {
-       *(*uint16)(v.addr) = i
+// Set sets v to the value x.
+func (v *Uint16Value) Set(x uint16) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uint16)(v.addr) = x;
 }
 
-// -- 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
+type Uint32Value struct {
+       value;
 }
 
-func uint32Creator(typ Type, addr Addr) Value {
-       return &uint32ValueStruct{ commonValue{Uint32Kind, typ, addr} }
+// Get returns the underlying uint32 value.
+func (v *Uint32Value) Get() uint32 {
+       return *(*uint32)(v.addr);
 }
 
-func (v *uint32ValueStruct) Get() uint32 {
-       return *(*uint32)(v.addr)
-}
-
-func (v *uint32ValueStruct) Set(i uint32) {
-       *(*uint32)(v.addr) = i
+// Set sets v to the value x.
+func (v *Uint32Value) Set(x uint32) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uint32)(v.addr) = x;
 }
 
-// -- 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
+type Uint64Value struct {
+       value;
 }
 
-func uint64Creator(typ Type, addr Addr) Value {
-       return &uint64ValueStruct{ commonValue{Uint64Kind, typ, addr} }
+// Get returns the underlying uint64 value.
+func (v *Uint64Value) Get() uint64 {
+       return *(*uint64)(v.addr);
 }
 
-func (v *uint64ValueStruct) Get() uint64 {
-       return *(*uint64)(v.addr)
-}
-
-func (v *uint64ValueStruct) Set(i uint64) {
-       *(*uint64)(v.addr) = i
+// Set sets v to the value x.
+func (v *Uint64Value) Set(x uint64) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uint64)(v.addr) = x;
 }
 
-// -- 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)
+type UintptrValue struct {
+       value;
 }
 
-func (v *uintptrValueStruct) Set(i uintptr) {
-       *(*uintptr)(v.addr) = i
+// Get returns the underlying uintptr value.
+func (v *UintptrValue) Get() uintptr {
+       return *(*uintptr)(v.addr);
 }
 
-// -- Float
-
-// FloatValue represents a float value.
-type FloatValue interface {
-       Value;
-       Get()   float;  // Get the underlying float.
-       Set(float);     // Get the underlying float.
+// Set sets v to the value x.
+func (v *UintptrValue) Set(x uintptr) {
+       if !v.canSet {
+               panic(cannotSet);
+       }
+       *(*uintptr)(v.addr) = x;
 }
 
-type floatValueStruct struct {
-       commonValue
+// UnsafePointerValue represents an unsafe.Pointer value.
+type UnsafePointerValue struct {
+       value;
 }
 
-func floatCreator(typ Type, addr Addr) Value {
-       return &floatValueStruct{ commonValue{FloatKind, typ, addr} }
+// 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));
 }
 
-func (v *floatValueStruct) Get() float {
-       return *(*float)(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 (v *floatValueStruct) Set(f float) {
-       *(*float)(v.addr) = f
+func typesMustMatch(t1, t2 reflect.Type) {
+       if t1 != t2 {
+               panicln("type mismatch:", t1, "!=", t2);
+       }
 }
 
-// -- Float32
+/*
+ * array
+ */
 
-// Float32Value represents a float32 value.
-type Float32Value interface {
+// ArrayOrSliceValue is the common interface
+// implemented by both ArrayValue and SliceValue.
+type ArrayOrSliceValue 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)
+       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;
 }
 
-func (v *float32ValueStruct) Set(f float32) {
-       *(*float32)(v.addr) = f
+// An ArrayValue represents an array.
+type ArrayValue struct {
+       value
 }
 
-// -- Float64
-
-// Float64Value represents a float64 value.
-type Float64Value interface {
-       Value;
-       Get()   float64;        // Get the underlying float64.
-       Set(float64);   // Get the underlying float64.
+// Len returns the length of the array.
+func (v *ArrayValue) Len() int {
+       return v.typ.(*ArrayType).Len();
 }
 
-type float64ValueStruct struct {
-       commonValue
+// Cap returns the capacity of the array (equal to Len()).
+func (v *ArrayValue) Cap() int {
+       return v.typ.(*ArrayType).Len();
 }
 
-func float64Creator(typ Type, addr Addr) Value {
-       return &float64ValueStruct{ commonValue{Float64Kind, typ, addr} }
+// addr returns the base address of the data in the array.
+func (v *ArrayValue) addr() addr {
+       return v.value.addr;
 }
 
-func (v *float64ValueStruct) Get() float64 {
-       return *(*float64)(v.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);
 }
 
-func (v *float64ValueStruct) Set(f float64) {
-       *(*float64)(v.addr) = f
+// 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);
 }
 
-// -- String
+/*
+ * slice
+ */
 
-// StringValue represents a string value.
-type StringValue interface {
-       Value;
-       Get()   string; // Get the underlying string value.
-       Set(string);    // Set the underlying string value.
+// runtime representation of slice
+type SliceHeader struct {
+       Data uintptr;
+       Len uint32;
+       Cap uint32;
 }
 
-type stringValueStruct struct {
-       commonValue
+// A SliceValue represents a slice.
+type SliceValue struct {
+       value
 }
 
-func stringCreator(typ Type, addr Addr) Value {
-       return &stringValueStruct{ commonValue{StringKind, typ, addr} }
+func (v *SliceValue) slice() *SliceHeader {
+       return (*SliceHeader)(v.value.addr);
 }
 
-func (v *stringValueStruct) Get() string {
-       return *(*string)(v.addr)
+// IsNil returns whether v is a nil slice.
+func (v *SliceValue) IsNil() bool {
+       return v.slice().Data == 0;
 }
 
-func (v *stringValueStruct) Set(s string) {
-       *(*string)(v.addr) = s
+// Len returns the length of the slice.
+func (v *SliceValue) Len() int {
+       return int(v.slice().Len);
 }
 
-// -- Bool
-
-// BoolValue represents a bool value.
-type BoolValue interface {
-       Value;
-       Get()   bool;   // Get the underlying bool value.
-       Set(bool);      // Set the underlying bool value.
+// Cap returns the capacity of the slice.
+func (v *SliceValue) Cap() int {
+       return int(v.slice().Cap);
 }
 
-type boolValueStruct struct {
-       commonValue
+// addr returns the base address of the data in the slice.
+func (v *SliceValue) addr() addr {
+       return addr(v.slice().Data);
 }
 
-func boolCreator(typ Type, addr Addr) Value {
-       return &boolValueStruct{ commonValue{BoolKind, typ, addr} }
+// 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);
+       }
+       s.Len = uint32(n);
 }
 
-func (v *boolValueStruct) Get() bool {
-       return *(*bool)(v.addr)
+// 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);
+       }
+       typesMustMatch(v.typ, x.typ);
+       *v.slice() = *x.slice();
 }
 
-func (v *boolValueStruct) Set(b bool) {
-       *(*bool)(v.addr) = b
+// 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);
+       }
+       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);
+}
+
+// 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);
+       }
+       p := addr(uintptr(v.addr()) + uintptr(i)*typ.Size());
+       return newValue(typ, p, v.canSet);
 }
 
-// -- 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;
+// 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);
 }
 
-type ptrValueStruct struct {
-       commonValue
-}
+/*
+ * chan
+ */
 
-func (v *ptrValueStruct) Get() Addr {
-       return *(*Addr)(v.addr)
+// A ChanValue represents a chan.
+type ChanValue struct {
+       value
 }
 
-func (v *ptrValueStruct) IsNil() bool {
-       return uintptr(*(*Addr)(v.addr)) == 0
+// IsNil returns whether v is a nil channel.
+func (v *ChanValue) IsNil() bool {
+       return *(*uintptr)(v.addr) == 0;
 }
 
-func (v *ptrValueStruct) Sub() Value {
-       if v.IsNil() {
-               return nil
+// 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);
        }
-       return newValueAddr(v.typ.(PtrType).Sub(), v.Get());
+       typesMustMatch(v.typ, x.typ);
+       *(*uintptr)(v.addr) = *(*uintptr)(x.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();
+// Get returns the uintptr value of v.
+// It is mainly useful for printing.
+func (v *ChanValue) Get() uintptr {
+       return *(*uintptr)(v.addr);
 }
 
-func ptrCreator(typ Type, addr Addr) Value {
-       return &ptrValueStruct{ commonValue{PtrKind, typ, addr} };
+// Send sends x on the channel v.
+func (v *ChanValue) Send(x Value) {
+       panic("unimplemented: channel Send");
 }
 
-// -- 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;
+// Recv receives and returns a value from the channel v.
+func (v *ChanValue) Recv() Value {
+       panic("unimplemented: channel Receive");
 }
 
-func copyArray(dst ArrayValue, src ArrayValue, n int);
-
-/*
-       Run-time representation of slices looks like this:
-               struct  Slice {
-                       byte*   array;          // actual data
-                       uint32  nel;            // number of elements
-                       uint32  cap;
-               };
-*/
-
-// 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.
-type SliceHeader struct {
-       Data    uintptr;
-       Len     uint32;
-       Cap     uint32;
+// 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");
 }
 
-type sliceValueStruct struct {
-       commonValue;
-       elemtype        Type;
-       elemsize        int;
-       slice *SliceHeader;
+// 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 (v *sliceValueStruct) IsSlice() bool {
-       return true
-}
+/*
+ * func
+ */
 
-func (v *sliceValueStruct) Len() int {
-       return int(v.slice.Len);
+// A FuncValue represents a function value.
+type FuncValue struct {
+       value
 }
 
-func (v *sliceValueStruct) Cap() int {
-       return int(v.slice.Cap);
+// IsNil returns whether v is a nil function.
+func (v *FuncValue) IsNil() bool {
+       return *(*uintptr)(v.addr) == 0;
 }
 
-func (v *sliceValueStruct) SetLen(len int) {
-       if len > v.Cap() {
-               panicln("reflect: sliceValueStruct.SetLen", len, v.Cap());
-       }
-       v.slice.Len = uint32(len);
+// Get returns the uintptr value of v.
+// It is mainly useful for printing.
+func (v *FuncValue) Get() uintptr {
+       return *(*uintptr)(v.addr);
 }
 
-func (v *sliceValueStruct) Set(src ArrayValue) {
-       if !src.IsSlice() {
-               panic("can't set slice from array");
-       }
-       s := src.(*sliceValueStruct);
-       if !equalType(v.typ, s.typ) {
-               panicln("incompatible types in ArrayValue.Set()");
+// 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);
        }
-       *v.slice = *s.slice;
+       typesMustMatch(v.typ, x.typ);
+       *(*uintptr)(v.addr) = *(*uintptr)(x.addr);
 }
 
-func (v *sliceValueStruct) Elem(i int) Value {
-       data_uint := v.slice.Data + uintptr(i * v.elemsize);
-       return newValueAddr(v.elemtype, Addr(data_uint));
+// 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");
 }
 
-func (v *sliceValueStruct) CopyFrom(src ArrayValue, n int) {
-       copyArray(v, src, n);
-}
 
-func (v *sliceValueStruct) IsNil() bool {
-       return v.slice.Data == 0
-}
+/*
+ * interface
+ */
 
-type arrayValueStruct struct {
-       commonValue;
-       elemtype        Type;
-       elemsize        int;
-       len     int;
+// An InterfaceValue represents an interface value.
+type InterfaceValue struct {
+       value
 }
 
-func (v *arrayValueStruct) IsSlice() bool {
-       return false
-}
+// No Get because v.Interface() is available.
 
-func (v *arrayValueStruct) Len() int {
-       return v.len
+// IsNil returns whether v is a nil interface value.
+func (v *InterfaceValue) IsNil() bool {
+       return v.Interface() == nil;
 }
 
-func (v *arrayValueStruct) Cap() int {
-       return v.len
+// Elem returns the concrete value stored in the interface value v.
+func (v *InterfaceValue) Elem() Value {
+       return NewValue(v.Interface());
 }
 
-func (v *arrayValueStruct) SetLen(len int) {
-       panicln("can't set len of array");
-}
+// 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;
+       }
 
-func (v *arrayValueStruct) Set(src ArrayValue) {
-       panicln("can't set array");
+       // Non-empty interface requires a runtime check.
+       panic("unimplemented: interface Set");
+//     unsafe.SetInterface(v.typ, v.addr, x);
 }
 
-func (v *arrayValueStruct) Elem(i int) Value {
-       data_uint := uintptr(v.addr) + uintptr(i * v.elemsize);
-       return newValueAddr(v.elemtype, Addr(data_uint));
-}
+/*
+ * map
+ */
 
-func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
-       copyArray(v, src, n);
+// A MapValue represents a map value.
+type MapValue struct {
+       value
 }
 
-func (v *arrayValueStruct) IsNil() bool {
-       return false
+// IsNil returns whether v is a nil map value.
+func (v *MapValue) IsNil() bool {
+       return *(*uintptr)(v.addr) == 0;
 }
 
-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;
+// 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);
        }
-       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();
-       return v;
-}
-
-// -- Map      TODO: finish and test
-
-// 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;
-}
-
-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
+       typesMustMatch(v.typ, x.typ);
+       *(*uintptr)(v.addr) = *(*uintptr)(x.addr);
 }
 
-func (v *mapValueStruct) IsNil() bool {
-       return false    // TODO: implement this properly
+// 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");
 }
 
-func (v *mapValueStruct) Elem(key Value) Value {
-       panic("map value element");
-       return nil
+// Len returns the number of keys in the map v.
+func (v *MapValue) Len() int {
+       panic("unimplemented: map Len");
 }
 
-// -- Chan
-
-// ChanValue represents a chan value.
-// Its implementation is incomplete.
-type ChanValue interface {
-       Value;
-       IsNil() bool;
+// Keys returns a slice containing all the keys present in the map,
+// in unspecified order.
+func (v *MapValue) Keys() []Value {
+       panic("unimplemented: map Keys");
 }
 
-type chanValueStruct struct {
-       commonValue
-}
+/*
+ * ptr
+ */
 
-func (v *chanValueStruct) IsNil() bool {
-       return false    // TODO: implement this properly
+// A PtrValue represents a pointer.
+type PtrValue struct {
+       value
 }
 
-func chanCreator(typ Type, addr Addr) Value {
-       return &chanValueStruct{ commonValue{ChanKind, typ, addr} }
+// IsNil returns whether v is a nil pointer.
+func (v *PtrValue) IsNil() bool {
+       return *(*uintptr)(v.addr) == 0;
 }
 
-// -- 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.
+// Get returns the uintptr value of v.
+// It is mainly useful for printing.
+func (v *PtrValue) Get() uintptr {
+       return *(*uintptr)(v.addr);
 }
 
-type structValueStruct struct {
-       commonValue;
-       field   []Value;
+// 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);
 }
 
-func (v *structValueStruct) Len() int {
-       return len(v.field)
+// 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();
 }
 
-func (v *structValueStruct) Field(i int) Value {
-       return v.field[i]
+// 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);
 }
 
-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));
+// 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();
        }
-       v.typ = typ;
        return v;
 }
 
-// -- Interface
-
-// InterfaceValue represents an interface value.
-type InterfaceValue interface {
-       Value;
-       Get()   interface {};   // Get the underlying interface{} value.
-       Value() Value;
-       IsNil() bool;
-}
+/*
+ * struct
+ */
 
-type interfaceValueStruct struct {
-       commonValue
+// A StructValue represents a struct value.
+type StructValue struct {
+       value
 }
 
-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)
+// 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);
        }
-       // Extract from v.addr as interface value with methods.
-       return *(*interface{ m() })(v.addr)
+       typesMustMatch(v.typ, x.typ);
+       memmove(uintptr(v.addr), uintptr(x.addr), v.typ.Size());
 }
 
-func (v *interfaceValueStruct) Interface() interface{} {
-       return v.Get();
-}
-
-func (v *interfaceValueStruct) Value() Value {
-       i := v.Get();
-       if i == nil {
+// 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;
        }
-       return NewValue(i);
-}
-
-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
+       f := t.Field(i);
+       return newValue(f.Type, addr(uintptr(v.addr)+f.Offset), v.canSet && f.PkgPath == "");
 }
 
-func (v *funcValueStruct) Get() Addr {
-       return *(*Addr)(v.addr)
+// NumField returns the number of fields in the struct.
+func (v *StructValue) NumField() int {
+       return v.typ.(*StructType).NumField();
 }
 
-func (v *funcValueStruct) IsNil() bool {
-       return *(*Addr)(v.addr) == nil
-}
-
-func funcCreator(typ Type, addr Addr) Value {
-       return &funcValueStruct{ commonValue{FuncKind, typ, addr} }
-}
+/*
+ * constructors
+ */
 
-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,
+// Typeof returns the reflection Type of the value in the interface{}.
+func Typeof(i interface{}) Type {
+       return toType(unsafe.Typeof(i));
 }
 
-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());
+// 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 c(typ, addr);
-}
-
-// NewZeroValue creates a new, zero-initialized Value for the specified Type.
-func NewZeroValue(typ Type) Value {
-       size := typ.Size();
-       if size == 0 {
-               size = 1;
+       t, a := unsafe.Reflect(i);
+       return newValue(toType(t), addr(a), true);
+}
+
+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);
        }
-       data := make([]uint8, size);
-       return newValueAddr(typ, Addr(&data[0]));
+       panicln("newValue", typ.String());
 }
 
-// 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
-       }
+func newFuncValue(typ Type, addr addr) *FuncValue {
+       return newValue(typ, addr, true).(*FuncValue);
+}
 
-       array := new(SliceHeader);
-       size := typ.Elem().Size() * cap;
+// 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);
-       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);
 }