]> Cypherpunks repositories - gostls13.git/commitdiff
Reflection values.
authorRob Pike <r@golang.org>
Wed, 22 Oct 2008 23:48:17 +0000 (16:48 -0700)
committerRob Pike <r@golang.org>
Wed, 22 Oct 2008 23:48:17 +0000 (16:48 -0700)
R=rsc
DELTA=206  (79 added, 25 deleted, 102 changed)
OCL=17652
CL=17669

usr/r/reflect/main.go
usr/r/reflect/tostring.go
usr/r/reflect/value.go

index d21b3933c5cdf7c6ddd47d1a3b304b8aed098d49..c00f2b9759bc771d15c9b7ac08f6053083734bba 100644 (file)
@@ -10,7 +10,7 @@ import (
 
 func typedump(s string) {
        t := reflect.ParseTypeString("", s);
-       print(reflect.TypeToString(t),"; size = ", t.Size(), "\n");
+       print(reflect.TypeToString(t, true),"; size = ", t.Size(), "\n");
 }
 
 func valuedump(s string) {
@@ -45,12 +45,13 @@ func valuedump(s string) {
 
 export type empty interface {}
 
-export type T struct { a int; b float64 }
+export type T struct { a int; b float64; c string; d *int }
 
 func main() {
        var s string;
        var t reflect.Type;
 
+if false{
        typedump("int8");
        typedump("int16");
        typedump("int32");
@@ -77,7 +78,7 @@ func main() {
        typedump("struct {a int8; b int8; c int8; b int32}");
        typedump("struct {a int8; b int8; c int8; d int8; b int32}");
        typedump("struct {a int8; b int8; c int8; d int8; e int8; b int32}");
-       
+
        valuedump("int8");
        valuedump("int16");
        valuedump("int32");
@@ -105,9 +106,50 @@ func main() {
        valuedump("struct {a int8; b int8; c int8; b int32}");
        valuedump("struct {a int8; b int8; c int8; d int8; b int32}");
        valuedump("struct {a int8; b int8; c int8; d int8; e int8; b int32}");
-
-       v := new(T);
-       a, b := sys.reflect(v.(empty));
-       println(a, b);
-       typedump(b);
+}
+{      var tmp = 123;
+       value := reflect.NewValue(tmp);
+       println(reflect.ValueToString(value));
+}
+{      var tmp = 123.4;
+       value := reflect.NewValue(tmp);
+       println(reflect.ValueToString(value));
+}
+{      var tmp = "abc";
+       value := reflect.NewValue(tmp);
+       println(reflect.ValueToString(value));
+}
+{
+       var i int = 7;
+       var tmp = &T{123, 456.0, "hello", &i};
+       value := reflect.NewValue(tmp);
+       println(reflect.ValueToString(value.(reflect.PtrValue).Sub()));
+}
+{
+       type C chan *T; // TODO: should not be necessary
+       var tmp = new(C);
+       value := reflect.NewValue(tmp);
+       println(reflect.ValueToString(value));
+}
+{
+       type A [10]int;
+       var tmp A = A{1,2,3,4,5,6,7,8,9,10};
+       value := reflect.NewValue(&tmp);
+       println(reflect.TypeToString(value.Type().(reflect.PtrType).Sub(), true));
+       println(reflect.TypeToString(value.(reflect.PtrValue).Sub().Type(), true));
+       println(reflect.ValueToString(value.(reflect.PtrValue).Sub()));
+       value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.Int32Value).Put(123);
+       println(reflect.ValueToString(value.(reflect.PtrValue).Sub()));
+}
+{
+       type AA []int;
+       tmp1 := [10]int{1,2,3,4,5,6,7,8,9,10};
+       var tmp *AA = &tmp1;
+       value := reflect.NewValue(tmp);
+       println(reflect.TypeToString(value.Type().(reflect.PtrType).Sub(), true));
+       println(reflect.TypeToString(value.(reflect.PtrValue).Sub().Type(), true));
+       println(reflect.ValueToString(value.(reflect.PtrValue).Sub()));
+       value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.Int32Value).Put(123);
+       println(reflect.ValueToString(value.(reflect.PtrValue).Sub()));
+}
 }
index f60013c002177302f80d210da5e70b0e3646a676..ca3ada9fdd644276ca7689f0978d8c54a1095d80 100644 (file)
@@ -12,7 +12,7 @@ import (
        "strings";
 )
 
-export func TypeToString(typ Type) string
+export func TypeToString(typ Type, expand bool) string
 export func ValueToString(val Value) string
 
 type HasFields interface {
@@ -24,7 +24,7 @@ func TypeFieldsToString(t HasFields, sep string) string {
        var str string;
        for i := 0; i < t.Len(); i++ {
                str1, typ, offset := t.Field(i);
-               str1 +=  " " + TypeToString(typ);
+               str1 +=  " " + TypeToString(typ, false);
                if i < t.Len() - 1 {
                        str1 += sep + " ";
                }
@@ -33,9 +33,9 @@ func TypeFieldsToString(t HasFields, sep string) string {
        return str;
 }
 
-func TypeToString(typ Type) string {
+func TypeToString(typ Type, expand bool) string {
        var str string;
-       if name := typ.Name(); name != "" {
+       if name := typ.Name(); !expand && name != "" {
                return name
        }
        switch(typ.Kind()) {
@@ -67,7 +67,7 @@ func TypeToString(typ Type) string {
                return "string";
        case PtrKind:
                p := typ.(PtrType);
-               return "*" + TypeToString(p.Sub());
+               return "*" + TypeToString(p.Sub(), false);
        case ArrayKind:
                a := typ.(ArrayType);
                if a.Open() {
@@ -75,11 +75,11 @@ func TypeToString(typ Type) string {
                } else {
                        str = "[" + strings.ltoa(int64(a.Len())) +  "]"
                }
-               return str + TypeToString(a.Elem());
+               return str + TypeToString(a.Elem(), false);
        case MapKind:
                m := typ.(MapType);
-               str = "map[" + TypeToString(m.Key()) + "]";
-               return str + TypeToString(m.Elem());
+               str = "map[" + TypeToString(m.Key(), false) + "]";
+               return str + TypeToString(m.Elem(), false);
        case ChanKind:
                c := typ.(ChanType);
                switch c.Dir() {
@@ -92,7 +92,7 @@ func TypeToString(typ Type) string {
                default:
                        panicln("reflect.TypeToString: unknown chan direction");
                }
-               return str + TypeToString(c.Elem());
+               return str + TypeToString(c.Elem(), false);
        case StructKind:
                return "struct{" + TypeFieldsToString(typ, ";") + "}";
        case InterfaceKind:
@@ -151,13 +151,13 @@ func ValueToString(val Value) string {
                return val.(StringValue).Get();
        case PtrKind:
                v := val.(PtrValue);
-               return TypeToString(typ) + "(" + integer(int64(v.Addr())) + ")";
+               return TypeToString(typ, false) + "(" + integer(int64(v.Indirect())) + ")";
        case ArrayKind:
                t := typ.(ArrayType);
                v := val.(ArrayValue);
-               str += TypeToString(t);
+               str += TypeToString(t, false);
                str += "{";
-               for i := 0; i < v.Len(); i++ {
+               for i := uint64(0); i < v.Len(); i++ {
                        if i > 0 {
                                str += ", "
                        }
@@ -168,7 +168,7 @@ func ValueToString(val Value) string {
        case MapKind:
                t := typ.(MapType);
                v := val.(ArrayValue);
-               str = TypeToString(t);
+               str = TypeToString(t, false);
                str += "{";
                str += "<can't iterate on maps>";
                str += "}";
@@ -178,7 +178,7 @@ func ValueToString(val Value) string {
        case StructKind:
                t := typ.(StructType);
                v := val.(StructValue);
-               str += TypeToString(t); // TODO: use the name?
+               str += TypeToString(t, false);
                str += "{";
                for i := 0; i < v.Len(); i++ {
                        if i > 0 {
index 30f5193e0f24471a47dd6e54c997d8c07ed97522..a180b8140ae008ba6985b7a5a74669e4587f9e6b 100644 (file)
@@ -11,6 +11,7 @@ import (
        "reflect";
 )
 
+
 type Addr uint64       // TODO: where are ptrint/intptr etc?
 
 export type Value interface {
@@ -24,31 +25,20 @@ type Creator *(typ Type, addr Addr) Value
 
 // Conversion functions, implemented in assembler
 func AddrToPtrAddr(Addr) *Addr
-func PtrAddrToAddr(*Addr) Addr
 func AddrToPtrInt8(Addr) *int8
-func PtrInt8ToAddr(*int8) Addr
 func AddrToPtrInt16(Addr) *int16
-func PtrInt16ToAddr(*int16) Addr
 func AddrToPtrInt32(Addr) *int32
-func PtrInt32ToAddr(*int32) Addr
 func AddrToPtrInt64(Addr) *int64
-func PtrInt64ToAddr(*int64) Addr
 func AddrToPtrUint8(Addr) *uint8
 func PtrUint8ToAddr(*uint8) Addr
 func AddrToPtrUint16(Addr) *uint16
-func PtrUint16ToAddr(*uint16) Addr
 func AddrToPtrUint32(Addr) *uint32
-func PtrUint32ToAddr(*uint32) Addr
 func AddrToPtrUint64(Addr) *uint64
 func PtrUint64ToAddr(*uint64) Addr
 func AddrToPtrFloat32(Addr) *float32
-func PtrFloat32ToAddr(*float32) Addr
 func AddrToPtrFloat64(Addr) *float64
-func PtrFloat64ToAddr(*float64) Addr
 func AddrToPtrFloat80(Addr) *float80
-func PtrFloat80ToAddr(*float80) Addr
 func AddrToPtrString(Addr) *string
-func PtrStringToAddr(*string) Addr
 
 // -- Int8
 
@@ -60,7 +50,7 @@ export type Int8Value interface {
 }
 
 type Int8ValueStruct struct {
-       p       *int8
+       addr    Addr
 }
 
 func (v *Int8ValueStruct) Kind() int {
@@ -72,16 +62,16 @@ func (v *Int8ValueStruct) Type() Type {
 }
 
 func (v *Int8ValueStruct) Get() int8 {
-       return *v.p
+       return *AddrToPtrInt8(v.addr)
 }
 
 func (v *Int8ValueStruct) Put(i int8) {
-       *v.p = i
+       *AddrToPtrInt8(v.addr) = i
 }
 
 func Int8Creator(typ Type, addr Addr) Value {
        v := new(Int8ValueStruct);
-       v.p = AddrToPtrInt8(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -95,7 +85,7 @@ export type Int16Value interface {
 }
 
 type Int16ValueStruct struct {
-       p       *int16
+       addr    Addr
 }
 
 func (v *Int16ValueStruct) Kind() int {
@@ -107,16 +97,16 @@ func (v *Int16ValueStruct) Type() Type {
 }
 
 func (v *Int16ValueStruct) Get() int16 {
-       return *v.p
+       return *AddrToPtrInt16(v.addr)
 }
 
 func (v *Int16ValueStruct) Put(i int16) {
-       *v.p = i
+       *AddrToPtrInt16(v.addr) = i
 }
 
 func Int16Creator(typ Type, addr Addr) Value {
        v := new(Int16ValueStruct);
-       v.p = AddrToPtrInt16(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -130,7 +120,7 @@ export type Int32Value interface {
 }
 
 type Int32ValueStruct struct {
-       p       *int32
+       addr    Addr
 }
 
 func (v *Int32ValueStruct) Type() Type {
@@ -142,16 +132,16 @@ func (v *Int32ValueStruct) Kind() int {
 }
 
 func (v *Int32ValueStruct) Get() int32 {
-       return *v.p
+       return *AddrToPtrInt32(v.addr)
 }
 
 func (v *Int32ValueStruct) Put(i int32) {
-       *v.p = i
+       *AddrToPtrInt32(v.addr) = i
 }
 
 func Int32Creator(typ Type, addr Addr) Value {
        v := new(Int32ValueStruct);
-       v.p = AddrToPtrInt32(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -165,7 +155,7 @@ export type Int64Value interface {
 }
 
 type Int64ValueStruct struct {
-       p       *int64
+       addr    Addr
 }
 
 func (v *Int64ValueStruct) Kind() int {
@@ -177,16 +167,16 @@ func (v *Int64ValueStruct) Type() Type {
 }
 
 func (v *Int64ValueStruct) Get() int64 {
-       return *v.p
+       return *AddrToPtrInt64(v.addr)
 }
 
 func (v *Int64ValueStruct) Put(i int64) {
-       *v.p = i
+       *AddrToPtrInt64(v.addr) = i
 }
 
 func Int64Creator(typ Type, addr Addr) Value {
        v := new(Int64ValueStruct);
-       v.p = AddrToPtrInt64(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -200,7 +190,7 @@ export type Uint8Value interface {
 }
 
 type Uint8ValueStruct struct {
-       p       *uint8
+       addr    Addr
 }
 
 func (v *Uint8ValueStruct) Kind() int {
@@ -212,16 +202,16 @@ func (v *Uint8ValueStruct) Type() Type {
 }
 
 func (v *Uint8ValueStruct) Get() uint8 {
-       return *v.p
+       return *AddrToPtrUint8(v.addr)
 }
 
 func (v *Uint8ValueStruct) Put(i uint8) {
-       *v.p = i
+       *AddrToPtrUint8(v.addr) = i
 }
 
 func Uint8Creator(typ Type, addr Addr) Value {
        v := new(Uint8ValueStruct);
-       v.p = AddrToPtrUint8(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -235,7 +225,7 @@ export type Uint16Value interface {
 }
 
 type Uint16ValueStruct struct {
-       p       *uint16
+       addr    Addr
 }
 
 func (v *Uint16ValueStruct) Kind() int {
@@ -247,16 +237,16 @@ func (v *Uint16ValueStruct) Type() Type {
 }
 
 func (v *Uint16ValueStruct) Get() uint16 {
-       return *v.p
+       return *AddrToPtrUint16(v.addr)
 }
 
 func (v *Uint16ValueStruct) Put(i uint16) {
-       *v.p = i
+       *AddrToPtrUint16(v.addr) = i
 }
 
 func Uint16Creator(typ Type, addr Addr) Value {
        v := new(Uint16ValueStruct);
-       v.p = AddrToPtrUint16(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -270,7 +260,7 @@ export type Uint32Value interface {
 }
 
 type Uint32ValueStruct struct {
-       p       *uint32
+       addr    Addr
 }
 
 func (v *Uint32ValueStruct) Kind() int {
@@ -282,16 +272,16 @@ func (v *Uint32ValueStruct) Type() Type {
 }
 
 func (v *Uint32ValueStruct) Get() uint32 {
-       return *v.p
+       return *AddrToPtrUint32(v.addr)
 }
 
 func (v *Uint32ValueStruct) Put(i uint32) {
-       *v.p = i
+       *AddrToPtrUint32(v.addr) = i
 }
 
 func Uint32Creator(typ Type, addr Addr) Value {
        v := new(Uint32ValueStruct);
-       v.p = AddrToPtrUint32(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -305,7 +295,7 @@ export type Uint64Value interface {
 }
 
 type Uint64ValueStruct struct {
-       p       *uint64
+       addr    Addr
 }
 
 func (v *Uint64ValueStruct) Kind() int {
@@ -317,16 +307,16 @@ func (v *Uint64ValueStruct) Type() Type {
 }
 
 func (v *Uint64ValueStruct) Get() uint64 {
-       return *v.p
+       return *AddrToPtrUint64(v.addr)
 }
 
 func (v *Uint64ValueStruct) Put(i uint64) {
-       *v.p = i
+       *AddrToPtrUint64(v.addr) = i
 }
 
 func Uint64Creator(typ Type, addr Addr) Value {
        v := new(Uint64ValueStruct);
-       v.p = AddrToPtrUint64(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -340,7 +330,7 @@ export type Float32Value interface {
 }
 
 type Float32ValueStruct struct {
-       p       *float32
+       addr    Addr
 }
 
 func (v *Float32ValueStruct) Kind() int {
@@ -352,16 +342,16 @@ func (v *Float32ValueStruct) Type() Type {
 }
 
 func (v *Float32ValueStruct) Get() float32 {
-       return *v.p
+       return *AddrToPtrFloat32(v.addr)
 }
 
 func (v *Float32ValueStruct) Put(f float32) {
-       *v.p = f
+       *AddrToPtrFloat32(v.addr) = f
 }
 
 func Float32Creator(typ Type, addr Addr) Value {
        v := new(Float32ValueStruct);
-       v.p = AddrToPtrFloat32(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -375,7 +365,7 @@ export type Float64Value interface {
 }
 
 type Float64ValueStruct struct {
-       p       *float64
+       addr    Addr
 }
 
 func (v *Float64ValueStruct) Kind() int {
@@ -387,16 +377,16 @@ func (v *Float64ValueStruct) Type() Type {
 }
 
 func (v *Float64ValueStruct) Get() float64 {
-       return *v.p
+       return *AddrToPtrFloat64(v.addr)
 }
 
 func (v *Float64ValueStruct) Put(f float64) {
-       *v.p = f
+       *AddrToPtrFloat64(v.addr) = f
 }
 
 func Float64Creator(typ Type, addr Addr) Value {
        v := new(Float64ValueStruct);
-       v.p = AddrToPtrFloat64(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -410,7 +400,7 @@ export type Float80Value interface {
 }
 
 type Float80ValueStruct struct {
-       p       *float80
+       addr    Addr
 }
 
 func (v *Float80ValueStruct) Kind() int {
@@ -424,18 +414,18 @@ func (v *Float80ValueStruct) Type() Type {
 /*
 BUG: can't gen code for float80s
 func (v *Float80ValueStruct) Get() float80 {
-       return *v.p
+       return *AddrToPtrFloat80(v.addr)
        return 0;
 }
 
 func (v *Float80ValueStruct) Put(f float80) {
-       *v.p = f
+       *AddrToPtrFloat80(v.addr) = f
 }
 */
 
 func Float80Creator(typ Type, addr Addr) Value {
        v := new(Float80ValueStruct);
-       v.p = AddrToPtrFloat80(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -449,7 +439,7 @@ export type StringValue interface {
 }
 
 type StringValueStruct struct {
-       p       *string
+       addr    Addr
 }
 
 func (v *StringValueStruct) Kind() int {
@@ -461,16 +451,16 @@ func (v *StringValueStruct) Type() Type {
 }
 
 func (v *StringValueStruct) Get() string {
-       return *v.p
+       return *AddrToPtrString(v.addr)
 }
 
 func (v *StringValueStruct) Put(s string) {
-       *v.p = s
+       *AddrToPtrString(v.addr) = s
 }
 
 func StringCreator(typ Type, addr Addr) Value {
        v := new(StringValueStruct);
-       v.p = AddrToPtrString(addr);
+       v.addr = addr;
        return v;
 }
 
@@ -480,11 +470,11 @@ export type PtrValue interface {
        Kind()  int;
        Sub()   Value;
        Type()  Type;
-       Addr()  Addr;
+       Indirect()      Addr;
 }
 
 type PtrValueStruct struct {
-       p       *Addr;
+       addr    Addr;
        typ     Type;
 }
 
@@ -496,19 +486,16 @@ func (v *PtrValueStruct) Type() Type {
        return v.typ
 }
 
-func (v *PtrValueStruct) Sub() Value {
-       return NewValueAddr(v.typ, *v.p);
+func (v *PtrValueStruct) Indirect() Addr {
+       return *AddrToPtrAddr(v.addr)
 }
 
-func (v *PtrValueStruct) Addr() Addr {
-       return *v.p
+func (v *PtrValueStruct) Sub() Value {
+       return NewValueAddr(v.typ.(PtrType).Sub(), v.Indirect());
 }
 
 func PtrCreator(typ Type, addr Addr) Value {
-       v := new(PtrValueStruct);
-       v.p = AddrToPtrAddr(addr);
-       v.typ = typ;
-       return v;
+       return &PtrValueStruct{addr, typ};
 }
 
 // -- Array    TODO: finish and test
@@ -517,15 +504,23 @@ export type ArrayValue interface {
        Kind()  int;
        Type()  Type;
        Open()  bool;
-       Len()   int;
-       Elem(i int)     Value;
+       Len()   uint64;
+       Elem(i uint64)  Value;
 }
 
 type OpenArrayValueStruct struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
-       len     int;
+       elemtype        Type;
+       elemsize        uint64;
 }
+/*
+       Run-time representation of open arrays looks like this:
+               struct  Array {
+                       byte*   array;          // actual data
+                       uint32  nel;            // number of elements
+               };
+*/
 
 func (v *OpenArrayValueStruct) Kind() int {
        return ArrayKind
@@ -539,21 +534,21 @@ func (v *OpenArrayValueStruct) Open() bool {
        return true
 }
 
-func (v *OpenArrayValueStruct) Len() int {
-       return v.len    // TODO: probably want this to be dynamic
+func (v *OpenArrayValueStruct) Len() uint64 {
+       return uint64(*AddrToPtrInt32(v.addr+8));
 }
 
-func (v *OpenArrayValueStruct) Elem(i int) Value {
-       panic("open array value element");
-       return nil
+func (v *OpenArrayValueStruct) Elem(i uint64) Value {
+       base := *AddrToPtrAddr(v.addr);
+       return NewValueAddr(v.elemtype, base + i * v.elemsize);
 }
 
 type FixedArrayValueStruct struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
-       len     int;
        elemtype        Type;
        elemsize        uint64;
+       len     uint64;
 }
 
 func (v *FixedArrayValueStruct) Kind() int {
@@ -568,12 +563,12 @@ func (v *FixedArrayValueStruct) Open() bool {
        return false
 }
 
-func (v *FixedArrayValueStruct) Len() int {
+func (v *FixedArrayValueStruct) Len() uint64 {
        return v.len
 }
 
-func (v *FixedArrayValueStruct) Elem(i int) Value {
-       return NewValueAddr(v.elemtype, v.data + uint64(i) * v.elemsize);
+func (v *FixedArrayValueStruct) Elem(i uint64) Value {
+       return NewValueAddr(v.elemtype, v.addr + i * v.elemsize);
        return nil
 }
 
@@ -581,15 +576,18 @@ func ArrayCreator(typ Type, addr Addr) Value {
        arraytype := typ.(ArrayType);
        if arraytype.Open() {
                v := new(OpenArrayValueStruct);
-               v.data = addr;
+               v.addr = addr;
                v.typ = typ;
+               v.elemtype = arraytype.Elem();
+               v.elemsize = v.elemtype.Size();
                return v;
        }
        v := new(FixedArrayValueStruct);
-       v.data = addr;
+       v.addr = addr;
        v.typ = typ;
        v.elemtype = arraytype.Elem();
-       v.elemsize = arraytype.Len();
+       v.elemsize = v.elemtype.Size();
+       v.len = arraytype.Len();
        return v;
 }
 
@@ -603,7 +601,7 @@ export type MapValue interface {
 }
 
 type MapValueStruct struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
        len     int;
 }
@@ -628,7 +626,7 @@ func (v *MapValueStruct) Elem(key Value) Value {
 func MapCreator(typ Type, addr Addr) Value {
        arraytype := typ.(MapType);
        v := new(MapValueStruct);
-       v.data = addr;
+       v.addr = addr;
        v.typ = typ;
        return v;
 }
@@ -641,7 +639,7 @@ export type ChanValue interface {
 }
 
 type ChanValueStruct struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
        len     int;
 }
@@ -656,7 +654,7 @@ func (v *ChanValueStruct) Type() Type {
 
 func ChanCreator(typ Type, addr Addr) Value {
        v := new(ChanValueStruct);
-       v.data = addr;
+       v.addr = addr;
        v.typ = typ;
        return v;
 }
@@ -671,6 +669,7 @@ export type StructValue interface {
 }
 
 type StructValueStruct struct {
+       addr    Addr;
        typ     Type;
        field   *[]Value;
 }
@@ -694,6 +693,7 @@ func (v *StructValueStruct) Field(i int) Value {
 func StructCreator(typ Type, addr Addr) Value {
        t := typ.(StructType);
        v := new(StructValueStruct);
+       v.addr = addr;
        nfield := t.Len();
        v.field = new([]Value, nfield);
        for i := 0; i < nfield; i++ {
@@ -712,7 +712,7 @@ export type InterfaceValue interface {
 }
 
 type InterfaceValueInterface struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
 }
 
@@ -726,7 +726,7 @@ func (v *InterfaceValueInterface) Type() Type {
 
 func InterfaceCreator(typ Type, addr Addr) Value {
        v := new(InterfaceValueInterface);
-       v.data = addr;
+       v.addr = addr;
        v.typ = typ;
        return v;
 }
@@ -739,7 +739,7 @@ export type FuncValue interface {
 }
 
 type FuncValueFunc struct {
-       data    Addr;
+       addr    Addr;
        typ     Type;
 }
 
@@ -753,7 +753,7 @@ func (v *FuncValueFunc) Type() Type {
 
 func FuncCreator(typ Type, addr Addr) Value {
        v := new(FuncValueFunc);
-       v.data = addr;
+       v.addr = addr;
        v.typ = typ;
        return v;
 }
@@ -791,8 +791,16 @@ func NewValueAddr(typ Type, addr Addr) Value {
        return c(typ, addr);
 }
 
-// TODO: do this better
 export func NewInitValue(typ Type) Value {
+       // Some values cannot be made this way.
+       switch typ.Kind() {
+       case FuncKind, ChanKind, MapKind:       // must be pointers, at least for now (TODO?)
+               return nil;
+       case ArrayKind:
+               if typ.(ArrayType).Open() {
+                       return nil
+               }
+       }
        size := typ.Size();
        if size == 0 {
                size = 1;
@@ -801,10 +809,14 @@ export func NewInitValue(typ Type) Value {
        return NewValueAddr(typ, PtrUint8ToAddr(&data[0]));
 }
 
-// TODO: do this better
-export func NewValue(e interface {}) Value {
-//     typestring, addr := sys.whathe(e);
-//     typ := ParseTypeString(typestring);
-//     return NewValueAddr(typ, addr);
-return nil
+export type Empty interface {}
+
+export func NewValue(e Empty) Value {
+       value, typestring  := sys.reflect(e);
+       typ := ParseTypeString("", typestring);
+       // Content of interface is a value; need a permanent copy to take its address
+       // so we can modify the contents. Values contain pointers to 'values'.
+       ap := new(uint64);
+       *ap = value;
+       return NewValueAddr(typ, PtrUint64ToAddr(ap));
 }