]> Cypherpunks repositories - gostls13.git/commitdiff
More reflection code.
authorRob Pike <r@golang.org>
Wed, 22 Oct 2008 18:02:56 +0000 (11:02 -0700)
committerRob Pike <r@golang.org>
Wed, 22 Oct 2008 18:02:56 +0000 (11:02 -0700)
Beginnings of values.
typestrings are grabbed from the environment.

R=rsc
APPROVED=rsc
DELTA=1046  (952 added, 3 deleted, 91 changed)
OCL=17593
CL=17621

usr/r/reflect/Makefile
usr/r/reflect/main.go
usr/r/reflect/tostring.go
usr/r/reflect/type.go
usr/r/reflect/typestring.c [new file with mode: 0644]
usr/r/reflect/value.go [new file with mode: 0644]

index 1d999f4e0a1f6d7e9c55afcab46284c8a5f8062a..b0927a3b891acf35650a1565c6e6e400f2376fc1 100644 (file)
@@ -3,7 +3,8 @@
 # license that can be found in the LICENSE file.
 
 # DO NOT EDIT.  Automatically generated by gobuild.
-# gobuild -m reflect tostring.go type.go value.go cast_amd64.s
+# gobuild -m reflect tostring.go type.go value.go cast_amd64.s\
+#    typestring.c
 O=6
 GC=$(O)g
 CC=$(O)c -w
@@ -33,6 +34,7 @@ clean:
 O1=\
        type.$O\
        cast_amd64.$O\
+       typestring.$O\
 
 O2=\
        value.$O\
index 1967ed7c3901840127c69a84aebb692689e7b822..f0a2c021d46bbb1f04d5fdb17af2d77b1c609bd6 100644 (file)
@@ -34,19 +34,23 @@ func valuedump(s string) {
        case reflect.Uint64Kind:
                v.(reflect.Uint64Value).Put(64);
        case reflect.Float32Kind:
-               v.(reflect.Float32Value).Put(320.0);
+               v.(reflect.Float32Value).Put(32.0);
        case reflect.Float64Kind:
-               v.(reflect.Float32Value).Put(640.0);
+               v.(reflect.Float64Value).Put(64.0);
        case reflect.StringKind:
                v.(reflect.StringValue).Put("stringy cheese");
        }
        print(s, " value = ", reflect.ValueToString(v), "\n");
 }
 
+export type empty interface {}
+
+export type T struct { a int; b float64 }
+
 func main() {
        var s string;
        var t reflect.Type;
-       
+
        typedump("int8");
        typedump("int16");
        typedump("int32");
@@ -82,5 +86,28 @@ func main() {
        valuedump("uint16");
        valuedump("uint32");
        valuedump("uint64");
+       valuedump("float32");
+       valuedump("float64");
        valuedump("string");
+       valuedump("*int8");
+       valuedump("**int8");
+       valuedump("[32]int32");
+       valuedump("**P.integer");
+       valuedump("[32]int32");
+       valuedump("[]int8");
+       valuedump("*map[string]int32");
+       valuedump("*chan<-string");
+       valuedump("struct {c *chan *int32; d float32}");
+       valuedump("*(a int8, b int32)");
+       valuedump("struct {c *(? *chan *P.integer, ? *int8)}");
+       valuedump("struct {a int8; b int32}");
+       valuedump("struct {a int8; b int8; b int32}");
+       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);
 }
index 0449a6e9e0fc6481739264ecae197972ce42d26a..17a0a79fc6f3602125172ffe649e515981453a64 100644 (file)
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Reflection library.
-// Formatting of types for debugging.
+// Formatting of types and values for debugging.
 
 package reflect
 
@@ -15,13 +15,17 @@ import (
 export func TypeToString(typ Type) string
 export func ValueToString(val Value) string
 
-func TypeFieldsToString(t Type, sep string) string {
-       s := t.(StructType);
+type HasFields interface {
+       Field(i int)    (name string, typ Type, offset uint64);
+       Len()   int;
+}
+
+func TypeFieldsToString(t HasFields, sep string) string {
        var str string;
-       for i := 0; i < s.Len(); i++ {
-               str1, t := s.Field(i);
-               str1 +=  " " + TypeToString(t);
-               if i < s.Len() - 1 {
+       for i := 0; i < t.Len(); i++ {
+               str1, typ, offset := t.Field(i);
+               str1 +=  " " + TypeToString(typ);
+               if i < t.Len() - 1 {
                        str1 += sep + " ";
                }
                str += str1;
@@ -33,7 +37,7 @@ func TypeToString(typ Type) string {
        var str string;
        switch(typ.Kind()) {
        case MissingKind:
-               return "missing";
+               return "$missing$";
        case Int8Kind:
                return "int8";
        case Int16Kind:
@@ -63,10 +67,10 @@ func TypeToString(typ Type) string {
                return "*" + TypeToString(p.Sub());
        case ArrayKind:
                a := typ.(ArrayType);
-               if a.Len() < 0 {
+               if a.Open() {
                        str = "[]"
                } else {
-                       str = "[" + strings.itoa(a.Len()) +  "]"
+                       str = "[" + strings.ltoa(int64(a.Len())) +  "]"
                }
                return str + TypeToString(a.Elem());
        case MapKind:
@@ -92,8 +96,7 @@ func TypeToString(typ Type) string {
                return "interface{" + TypeFieldsToString(typ, ";") + "}";
        case FuncKind:
                f := typ.(FuncType);
-               str = "func";
-               str += "(" + TypeFieldsToString(f.In(), ",") + ")";
+               str = "(" + TypeFieldsToString(f.In(), ",") + ")";
                if f.Out() != nil {
                        str += "(" + TypeFieldsToString(f.Out(), ",") + ")";
                }
@@ -106,7 +109,11 @@ func TypeToString(typ Type) string {
 
 // TODO: want an unsigned one too
 func integer(v int64) string {
-       return strings.itol(v);
+       return strings.ltoa(v);
+}
+
+func floatingpoint(v float64) string {
+       return strings.dtoa(v);
 }
 
 func ValueToString(val Value) string {
@@ -132,16 +139,56 @@ func ValueToString(val Value) string {
        case Uint64Kind:
                return integer(int64(val.(Uint64Value).Get()));
        case Float32Kind:
-               return "float32";
+               return floatingpoint(float64(val.(Float32Value).Get()));
        case Float64Kind:
-               return "float64";
+               return floatingpoint(float64(val.(Float64Value).Get()));
        case Float80Kind:
                return "float80";
        case StringKind:
                return val.(StringValue).Get();
        case PtrKind:
-               p := typ.(PtrType);
-               return ValueToString(p.Sub());
+               v := val.(PtrValue);
+               return TypeToString(typ) + "(" + integer(int64(v.Addr())) + ")";
+       case ArrayKind:
+               t := typ.(ArrayType);
+               v := val.(ArrayValue);
+               str += TypeToString(t);
+               str += "{";
+               for i := 0; i < v.Len(); i++ {
+                       if i > 0 {
+                               str += ", "
+                       }
+                       str += ValueToString(v.Elem(i));
+               }
+               str += "}";
+               return str;
+       case MapKind:
+               t := typ.(MapType);
+               v := val.(ArrayValue);
+               str = TypeToString(t);
+               str += "{";
+               str += "<can't iterate on maps>";
+               str += "}";
+               return str;
+       case ChanKind:
+               return "can't print chans yet";
+       case StructKind:
+               t := typ.(StructType);
+               v := val.(StructValue);
+               str += TypeToString(t); // TODO: use the name?
+               str += "{";
+               for i := 0; i < v.Len(); i++ {
+                       if i > 0 {
+                               str += ", "
+                       }
+                       str += ValueToString(v.Field(i));
+               }
+               str += "}";
+               return str;
+       case InterfaceKind:
+               return "can't print interfaces yet";
+       case FuncKind:
+               return "can't print funcs yet";
        default:
                panicln("reflect.ValueToString: can't print type ", val.Kind());
        }
index 9ed6c75e9eab6a76a7d4086e63615f9cb16610c3..39a3c3ae34b2f8c68af4b46e39b847bdc118581c 100644 (file)
@@ -11,7 +11,7 @@ export type Type interface
 
 export func ExpandType(name string) Type
 
-//export var GlobalTypeStrings = sys.typestrings;
+export func typestrings() string       // implemented in C; declared here
 
 export const (
        MissingKind = iota;
@@ -36,33 +36,39 @@ export const (
        Uint8Kind;
 )
 
-var ptrsize int
-var interfacesize int
+var ptrsize uint64
+var interfacesize uint64
 
-var MissingString = "missing"  // syntactic name for undefined type names
+var MissingString = "$missing$"        // syntactic name for undefined type names
 
 export type Type interface {
        Kind()  int;
-       Size()  int;
+       Size()  uint64;
 }
 
 // -- Basic
 
 type BasicType struct{
+       name    string;
        kind    int;
-       size    int;
+       size    uint64;
+}
+
+func (t *BasicType) Name() string {
+       return t.name
 }
 
 func (t *BasicType) Kind() int {
        return t.kind
 }
 
-func (t *BasicType) Size() int {
+func (t *BasicType) Size() uint64 {
        return t.size
 }
 
-func NewBasicType(k, size int) Type {
+func NewBasicType(n string, k int, size uint64) Type {
        t := new(BasicType);
+       t.name = n;
        t.kind = k;
        t.size = size;
        return t;
@@ -70,19 +76,19 @@ func NewBasicType(k, size int) Type {
 
 // Prebuilt basic types
 export var (
-       Missing = NewBasicType(MissingKind, 1);
-       Int8 = NewBasicType(Int8Kind, 1);
-       Int16 = NewBasicType(Int16Kind, 2);
-       Int32 = NewBasicType(Int32Kind, 4);
-       Int64 = NewBasicType(Int64Kind, 8);
-       Uint8 = NewBasicType(Uint8Kind, 1);
-       Uint16 = NewBasicType(Uint16Kind, 2);
-       Uint32 = NewBasicType(Uint32Kind, 4);
-       Uint64 = NewBasicType(Uint64Kind, 8);
-       Float32 = NewBasicType(Float32Kind, 4);
-       Float64 = NewBasicType(Float64Kind, 8);
-       Float80 = NewBasicType(Float80Kind, 10);        // TODO: strange size?
-       String = NewBasicType(StringKind, 8);   // implemented as a pointer
+       Missing = NewBasicType(MissingString, MissingKind, 1);
+       Int8 = NewBasicType("int8", Int8Kind, 1);
+       Int16 = NewBasicType("int16", Int16Kind, 2);
+       Int32 = NewBasicType("int32", Int32Kind, 4);
+       Int64 = NewBasicType("int64", Int64Kind, 8);
+       Uint8 = NewBasicType("uint8", Uint8Kind, 1);
+       Uint16 = NewBasicType("uint16", Uint16Kind, 2);
+       Uint32 = NewBasicType("uint32", Uint32Kind, 4);
+       Uint64 = NewBasicType("uint64", Uint64Kind, 8);
+       Float32 = NewBasicType("float32", Float32Kind, 4);
+       Float64 = NewBasicType("float64", Float64Kind, 8);
+       Float80 = NewBasicType("float80", Float80Kind, 10);     // TODO: strange size?
+       String = NewBasicType("string", StringKind, 8); // implemented as a pointer
 )
 
 // Stub types allow us to defer evaluating type names until needed.
@@ -126,7 +132,7 @@ func (t *PtrTypeStruct) Kind() int {
        return PtrKind
 }
 
-func (t *PtrTypeStruct) Size() int {
+func (t *PtrTypeStruct) Size() uint64 {
        return ptrsize
 }
 
@@ -143,28 +149,34 @@ func NewPtrTypeStruct(sub *StubType) *PtrTypeStruct {
 // -- Array
 
 export type ArrayType interface {
-       Len()   int;
+       Open()  bool;
+       Len()   uint64;
        Elem()  Type;
 }
 
 type ArrayTypeStruct struct {
        elem    *StubType;
-       len     int;
+       open    bool;   // otherwise fixed size
+       len     uint64;
 }
 
 func (t *ArrayTypeStruct) Kind() int {
        return ArrayKind
 }
 
-func (t *ArrayTypeStruct) Size() int {
-       if t.len < 0 {
+func (t *ArrayTypeStruct) Size() uint64 {
+       if t.open {
                return ptrsize  // open arrays are pointers to structures
        }
        return t.len * t.elem.Get().Size();
 }
 
-func (t *ArrayTypeStruct) Len() int {
-       // -1 is open array?  TODO
+func (t *ArrayTypeStruct) Open() bool {
+       return t.open
+}
+
+func (t *ArrayTypeStruct) Len() uint64 {
+       // what about open array?  TODO
        return t.len
 }
 
@@ -172,8 +184,9 @@ func (t *ArrayTypeStruct) Elem() Type {
        return t.elem.Get()
 }
 
-func NewArrayTypeStruct(len int, elem *StubType) *ArrayTypeStruct {
+func NewArrayTypeStruct(open bool, len uint64, elem *StubType) *ArrayTypeStruct {
        t := new(ArrayTypeStruct);
+       t.open = open;
        t.len = len;
        t.elem = elem;
        return t;
@@ -195,7 +208,7 @@ func (t *MapTypeStruct) Kind() int {
        return MapKind
 }
 
-func (t *MapTypeStruct) Size() int {
+func (t *MapTypeStruct) Size() uint64 {
        panic("reflect.type: map.Size(): cannot happen");
        return 0
 }
@@ -236,8 +249,8 @@ type ChanTypeStruct struct {
 func (t *ChanTypeStruct) Kind() int {
        return ChanKind
 }
-       
-func (t *ChanTypeStruct) Size() int {
+
+func (t *ChanTypeStruct) Size() uint64 {
        panic("reflect.type: chan.Size(): cannot happen");
        return 0
 }
@@ -261,14 +274,15 @@ func NewChanTypeStruct(dir int, elem *StubType) *ChanTypeStruct {
 // -- Struct
 
 export type StructType interface {
-       Field(int)      (name string, typ Type);
+       Field(int)      (name string, typ Type, offset uint64);
        Len()   int;
 }
 
 type Field struct {
        name    string;
        typ     *StubType;
-       size    int;
+       size    uint64;
+       offset  uint64;
 }
 
 type StructTypeStruct struct {
@@ -280,26 +294,30 @@ func (t *StructTypeStruct) Kind() int {
 }
 
 // TODO: not portable; depends on 6g
-func (t *StructTypeStruct) Size() int {
-       size := 0;
+func (t *StructTypeStruct) Size() uint64 {
+       size := uint64(0);
        for i := 0; i < len(t.field); i++ {
                elemsize := t.field[i].typ.Get().Size();
                // pad until at (elemsize mod 8) boundary
                align := elemsize - 1;
-               if align > 7 {  // BUG: we know structs are at 8-aligned
+               if align > 7 {  // BUG: we know structs are 8-aligned
                        align = 7
                }
                if align > 0 {
                        size = (size + align) & ^align;
                }
+               t.field[i].offset = size;
                size += elemsize;
        }
-       size = (size + 7) & ^7;
+       size = (size + 7) & ((1<<64 - 1) & ^7);
        return size;
 }
 
-func (t *StructTypeStruct) Field(i int) (name string, typ Type) {
-       return t.field[i].name, t.field[i].typ.Get()
+func (t *StructTypeStruct) Field(i int) (name string, typ Type, offset uint64) {
+       if t.field[i].offset == 0 {
+               t.Size();       // will compute offsets
+       }
+       return t.field[i].name, t.field[i].typ.Get(), t.field[i].offset
 }
 
 func (t *StructTypeStruct) Len() int {
@@ -315,7 +333,7 @@ func NewStructTypeStruct(field *[]Field) *StructTypeStruct {
 // -- Interface
 
 export type InterfaceType interface {
-       Field(int)      (name string, typ Type);
+       Field(int)      (name string, typ Type, offset uint64);
        Len()   int;
 }
 
@@ -323,8 +341,8 @@ type InterfaceTypeStruct struct {
        field   *[]Field;
 }
 
-func (t *InterfaceTypeStruct) Field(i int) (name string, typ Type) {
-       return t.field[i].name, t.field[i].typ.Get()
+func (t *InterfaceTypeStruct) Field(i int) (name string, typ Type, offset uint64) {
+       return t.field[i].name, t.field[i].typ.Get(), 0
 }
 
 func (t *InterfaceTypeStruct) Len() int {
@@ -341,7 +359,7 @@ func (t *InterfaceTypeStruct) Kind() int {
        return InterfaceKind
 }
 
-func (t *InterfaceTypeStruct) Size() int {
+func (t *InterfaceTypeStruct) Size() uint64 {
        return interfacesize
 }
 
@@ -361,7 +379,7 @@ func (t *FuncTypeStruct) Kind() int {
        return FuncKind
 }
 
-func (t *FuncTypeStruct) Size() int {
+func (t *FuncTypeStruct) Size() uint64 {
        panic("reflect.type: func.Size(): cannot happen");
        return 0
 }
@@ -388,10 +406,11 @@ func NewFuncTypeStruct(in, out *StructTypeStruct) *FuncTypeStruct {
 var types *map[string] *Type   // BUG TODO: should be Type not *Type
 
 // List of typename, typestring pairs
-var typestrings *map[string] string
+var typestring *map[string] string
+var initialized bool = false
 
 // Map of basic types to prebuilt StubTypes
-var basicstubs *map[string] *StubType
+var basicstub *map[string] *StubType
 
 var MissingStub *StubType;
 
@@ -414,11 +433,11 @@ func init() {
        Lock(); // not necessary because of init ordering but be safe.
 
        types = new(map[string] *Type);
-       typestrings = new(map[string] string);
-       basicstubs = new(map[string] *StubType);
+       typestring = new(map[string] string);
+       basicstub = new(map[string] *StubType);
 
        // Basics go into types table
-       types["missing"] = &Missing;
+       types[MissingString] = &Missing;
        types["int8"] = &Int8;
        types["int16"] = &Int16;
        types["int32"] = &Int32;
@@ -434,21 +453,19 @@ func init() {
 
        // Basics get prebuilt stubs
        MissingStub = NewStubType(Missing);
-       basicstubs["missing"] = MissingStub;
-       basicstubs["int8"] = NewStubType(Int8);
-       basicstubs["int16"] = NewStubType(Int16);
-       basicstubs["int32"] = NewStubType(Int32);
-       basicstubs["int64"] = NewStubType(Int64);
-       basicstubs["uint8"] = NewStubType(Uint8);
-       basicstubs["uint16"] = NewStubType(Uint16);
-       basicstubs["uint32"] = NewStubType(Uint32);
-       basicstubs["uint64"] = NewStubType(Uint64);
-       basicstubs["float32"] = NewStubType(Float32);
-       basicstubs["float64"] = NewStubType(Float64);
-       basicstubs["float80"] = NewStubType(Float80);
-       basicstubs["string"] = NewStubType(String);
-
-       typestrings["P.integer"] = "int32";     // TODO: for testing; remove
+       basicstub[MissingString] = MissingStub;
+       basicstub["int8"] = NewStubType(Int8);
+       basicstub["int16"] = NewStubType(Int16);
+       basicstub["int32"] = NewStubType(Int32);
+       basicstub["int64"] = NewStubType(Int64);
+       basicstub["uint8"] = NewStubType(Uint8);
+       basicstub["uint16"] = NewStubType(Uint16);
+       basicstub["uint32"] = NewStubType(Uint32);
+       basicstub["uint64"] = NewStubType(Uint64);
+       basicstub["float32"] = NewStubType(Float32);
+       basicstub["float64"] = NewStubType(Float64);
+       basicstub["float80"] = NewStubType(Float80);
+       basicstub["string"] = NewStubType(String);
 
        Unlock();
 }
@@ -557,7 +574,8 @@ func (p *Parser) Next() {
 func (p *Parser) Type() *StubType
 
 func (p *Parser) Array() *StubType {
-       size := -1;
+       size := uint64(0);
+       open := true;
        if p.token != "]" {
                if len(p.token) == 0 || !isdigit(p.token[0]) {
                        return MissingStub
@@ -565,16 +583,17 @@ func (p *Parser) Array() *StubType {
                // 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'
+                       size = size * 10 + uint64(p.token[i]) - '0'
                }
                p.Next();
+               open = false;
        }
        if p.token != "]" {
                return MissingStub
        }
        p.Next();
        elemtype := p.Type();
-       return NewStubType(NewArrayTypeStruct(size, elemtype));
+       return NewStubType(NewArrayTypeStruct(open, size, elemtype));
 }
 
 func (p *Parser) Map() *StubType {
@@ -715,7 +734,7 @@ func (p *Parser) Type() *StubType {
                return MissingStub;
        }
        // must be an identifier. is it basic? if so, we have a stub
-       if s, ok := basicstubs[p.token]; ok {
+       if s, ok := basicstub[p.token]; ok {
                p.Next();
                return s
        }
@@ -743,12 +762,50 @@ export func ParseTypeString(str string) Type {
        return p.Type().Get();
 }
 
+// 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 := typestrings[name];
+       s, ok := typestring[name];
        if !ok {
-               s = MissingString;
-               typestrings[name] = s;
+               InitializeTypeStrings();
+               s, ok = typestring[name];
+               if !ok {
+                       s = MissingString;
+                       typestring[name] = s;
+               }
        }
        return s
 }
diff --git a/usr/r/reflect/typestring.c b/usr/r/reflect/typestring.c
new file mode 100644 (file)
index 0000000..a5e6398
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+extern char gotypestrings[];   // really a go String, but we don't have the definition here
+
+void FLUSH(void *v) { }
+
+void reflect·typestrings(void *s) {
+       s = gotypestrings;
+       FLUSH(&s);
+}
diff --git a/usr/r/reflect/value.go b/usr/r/reflect/value.go
new file mode 100644 (file)
index 0000000..30f5193
--- /dev/null
@@ -0,0 +1,810 @@
+// 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.
+
+// Reflection library.
+// Handling values.
+
+package reflect
+
+import (
+       "reflect";
+)
+
+type Addr uint64       // TODO: where are ptrint/intptr etc?
+
+export type Value interface {
+       Kind()  int;
+       Type()  Type;
+}
+
+func NewValueAddr(typ Type, addr Addr) Value
+
+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
+
+export type Int8Value interface {
+       Kind()  int;
+       Get()   int8;
+       Put(int8);
+       Type()  Type;
+}
+
+type Int8ValueStruct struct {
+       p       *int8
+}
+
+func (v *Int8ValueStruct) Kind() int {
+       return Int8Kind
+}
+
+func (v *Int8ValueStruct) Type() Type {
+       return Int8
+}
+
+func (v *Int8ValueStruct) Get() int8 {
+       return *v.p
+}
+
+func (v *Int8ValueStruct) Put(i int8) {
+       *v.p = i
+}
+
+func Int8Creator(typ Type, addr Addr) Value {
+       v := new(Int8ValueStruct);
+       v.p = AddrToPtrInt8(addr);
+       return v;
+}
+
+// -- Int16
+
+export type Int16Value interface {
+       Kind()  int;
+       Get()   int16;
+       Put(int16);
+       Type()  Type;
+}
+
+type Int16ValueStruct struct {
+       p       *int16
+}
+
+func (v *Int16ValueStruct) Kind() int {
+       return Int16Kind
+}
+
+func (v *Int16ValueStruct) Type() Type {
+       return Int16
+}
+
+func (v *Int16ValueStruct) Get() int16 {
+       return *v.p
+}
+
+func (v *Int16ValueStruct) Put(i int16) {
+       *v.p = i
+}
+
+func Int16Creator(typ Type, addr Addr) Value {
+       v := new(Int16ValueStruct);
+       v.p = AddrToPtrInt16(addr);
+       return v;
+}
+
+// -- Int32
+
+export type Int32Value interface {
+       Kind()  int;
+       Get()   int32;
+       Put(int32);
+       Type()  Type;
+}
+
+type Int32ValueStruct struct {
+       p       *int32
+}
+
+func (v *Int32ValueStruct) Type() Type {
+       return Int32
+}
+
+func (v *Int32ValueStruct) Kind() int {
+       return Int32Kind
+}
+
+func (v *Int32ValueStruct) Get() int32 {
+       return *v.p
+}
+
+func (v *Int32ValueStruct) Put(i int32) {
+       *v.p = i
+}
+
+func Int32Creator(typ Type, addr Addr) Value {
+       v := new(Int32ValueStruct);
+       v.p = AddrToPtrInt32(addr);
+       return v;
+}
+
+// -- Int64
+
+export type Int64Value interface {
+       Kind()  int;
+       Get()   int64;
+       Put(int64);
+       Type()  Type;
+}
+
+type Int64ValueStruct struct {
+       p       *int64
+}
+
+func (v *Int64ValueStruct) Kind() int {
+       return Int64Kind
+}
+
+func (v *Int64ValueStruct) Type() Type {
+       return Int64
+}
+
+func (v *Int64ValueStruct) Get() int64 {
+       return *v.p
+}
+
+func (v *Int64ValueStruct) Put(i int64) {
+       *v.p = i
+}
+
+func Int64Creator(typ Type, addr Addr) Value {
+       v := new(Int64ValueStruct);
+       v.p = AddrToPtrInt64(addr);
+       return v;
+}
+
+// -- Uint8
+
+export type Uint8Value interface {
+       Kind()  int;
+       Get()   uint8;
+       Put(uint8);
+       Type()  Type;
+}
+
+type Uint8ValueStruct struct {
+       p       *uint8
+}
+
+func (v *Uint8ValueStruct) Kind() int {
+       return Uint8Kind
+}
+
+func (v *Uint8ValueStruct) Type() Type {
+       return Uint8
+}
+
+func (v *Uint8ValueStruct) Get() uint8 {
+       return *v.p
+}
+
+func (v *Uint8ValueStruct) Put(i uint8) {
+       *v.p = i
+}
+
+func Uint8Creator(typ Type, addr Addr) Value {
+       v := new(Uint8ValueStruct);
+       v.p = AddrToPtrUint8(addr);
+       return v;
+}
+
+// -- Uint16
+
+export type Uint16Value interface {
+       Kind()  int;
+       Get()   uint16;
+       Put(uint16);
+       Type()  Type;
+}
+
+type Uint16ValueStruct struct {
+       p       *uint16
+}
+
+func (v *Uint16ValueStruct) Kind() int {
+       return Uint16Kind
+}
+
+func (v *Uint16ValueStruct) Type() Type {
+       return Uint16
+}
+
+func (v *Uint16ValueStruct) Get() uint16 {
+       return *v.p
+}
+
+func (v *Uint16ValueStruct) Put(i uint16) {
+       *v.p = i
+}
+
+func Uint16Creator(typ Type, addr Addr) Value {
+       v := new(Uint16ValueStruct);
+       v.p = AddrToPtrUint16(addr);
+       return v;
+}
+
+// -- Uint32
+
+export type Uint32Value interface {
+       Kind()  int;
+       Get()   uint32;
+       Put(uint32);
+       Type()  Type;
+}
+
+type Uint32ValueStruct struct {
+       p       *uint32
+}
+
+func (v *Uint32ValueStruct) Kind() int {
+       return Uint32Kind
+}
+
+func (v *Uint32ValueStruct) Type() Type {
+       return Uint32
+}
+
+func (v *Uint32ValueStruct) Get() uint32 {
+       return *v.p
+}
+
+func (v *Uint32ValueStruct) Put(i uint32) {
+       *v.p = i
+}
+
+func Uint32Creator(typ Type, addr Addr) Value {
+       v := new(Uint32ValueStruct);
+       v.p = AddrToPtrUint32(addr);
+       return v;
+}
+
+// -- Uint64
+
+export type Uint64Value interface {
+       Kind()  int;
+       Get()   uint64;
+       Put(uint64);
+       Type()  Type;
+}
+
+type Uint64ValueStruct struct {
+       p       *uint64
+}
+
+func (v *Uint64ValueStruct) Kind() int {
+       return Uint64Kind
+}
+
+func (v *Uint64ValueStruct) Type() Type {
+       return Uint64
+}
+
+func (v *Uint64ValueStruct) Get() uint64 {
+       return *v.p
+}
+
+func (v *Uint64ValueStruct) Put(i uint64) {
+       *v.p = i
+}
+
+func Uint64Creator(typ Type, addr Addr) Value {
+       v := new(Uint64ValueStruct);
+       v.p = AddrToPtrUint64(addr);
+       return v;
+}
+
+// -- Float32
+
+export type Float32Value interface {
+       Kind()  int;
+       Get()   float32;
+       Put(float32);
+       Type()  Type;
+}
+
+type Float32ValueStruct struct {
+       p       *float32
+}
+
+func (v *Float32ValueStruct) Kind() int {
+       return Float32Kind
+}
+
+func (v *Float32ValueStruct) Type() Type {
+       return Float32
+}
+
+func (v *Float32ValueStruct) Get() float32 {
+       return *v.p
+}
+
+func (v *Float32ValueStruct) Put(f float32) {
+       *v.p = f
+}
+
+func Float32Creator(typ Type, addr Addr) Value {
+       v := new(Float32ValueStruct);
+       v.p = AddrToPtrFloat32(addr);
+       return v;
+}
+
+// -- Float64
+
+export type Float64Value interface {
+       Kind()  int;
+       Get()   float64;
+       Put(float64);
+       Type()  Type;
+}
+
+type Float64ValueStruct struct {
+       p       *float64
+}
+
+func (v *Float64ValueStruct) Kind() int {
+       return Float64Kind
+}
+
+func (v *Float64ValueStruct) Type() Type {
+       return Float64
+}
+
+func (v *Float64ValueStruct) Get() float64 {
+       return *v.p
+}
+
+func (v *Float64ValueStruct) Put(f float64) {
+       *v.p = f
+}
+
+func Float64Creator(typ Type, addr Addr) Value {
+       v := new(Float64ValueStruct);
+       v.p = AddrToPtrFloat64(addr);
+       return v;
+}
+
+// -- Float80
+
+export type Float80Value interface {
+       Kind()  int;
+       Get()   float80;
+       Put(float80);
+       Type()  Type;
+}
+
+type Float80ValueStruct struct {
+       p       *float80
+}
+
+func (v *Float80ValueStruct) Kind() int {
+       return Float80Kind
+}
+
+func (v *Float80ValueStruct) Type() Type {
+       return Float80
+}
+
+/*
+BUG: can't gen code for float80s
+func (v *Float80ValueStruct) Get() float80 {
+       return *v.p
+       return 0;
+}
+
+func (v *Float80ValueStruct) Put(f float80) {
+       *v.p = f
+}
+*/
+
+func Float80Creator(typ Type, addr Addr) Value {
+       v := new(Float80ValueStruct);
+       v.p = AddrToPtrFloat80(addr);
+       return v;
+}
+
+// -- String
+
+export type StringValue interface {
+       Kind()  int;
+       Get()   string;
+       Put(string);
+       Type()  Type;
+}
+
+type StringValueStruct struct {
+       p       *string
+}
+
+func (v *StringValueStruct) Kind() int {
+       return StringKind
+}
+
+func (v *StringValueStruct) Type() Type {
+       return String
+}
+
+func (v *StringValueStruct) Get() string {
+       return *v.p
+}
+
+func (v *StringValueStruct) Put(s string) {
+       *v.p = s
+}
+
+func StringCreator(typ Type, addr Addr) Value {
+       v := new(StringValueStruct);
+       v.p = AddrToPtrString(addr);
+       return v;
+}
+
+// -- Pointer
+
+export type PtrValue interface {
+       Kind()  int;
+       Sub()   Value;
+       Type()  Type;
+       Addr()  Addr;
+}
+
+type PtrValueStruct struct {
+       p       *Addr;
+       typ     Type;
+}
+
+func (v *PtrValueStruct) Kind() int {
+       return PtrKind
+}
+
+func (v *PtrValueStruct) Type() Type {
+       return v.typ
+}
+
+func (v *PtrValueStruct) Sub() Value {
+       return NewValueAddr(v.typ, *v.p);
+}
+
+func (v *PtrValueStruct) Addr() Addr {
+       return *v.p
+}
+
+func PtrCreator(typ Type, addr Addr) Value {
+       v := new(PtrValueStruct);
+       v.p = AddrToPtrAddr(addr);
+       v.typ = typ;
+       return v;
+}
+
+// -- Array    TODO: finish and test
+
+export type ArrayValue interface {
+       Kind()  int;
+       Type()  Type;
+       Open()  bool;
+       Len()   int;
+       Elem(i int)     Value;
+}
+
+type OpenArrayValueStruct struct {
+       data    Addr;
+       typ     Type;
+       len     int;
+}
+
+func (v *OpenArrayValueStruct) Kind() int {
+       return ArrayKind
+}
+
+func (v *OpenArrayValueStruct) Type() Type {
+       return v.typ
+}
+
+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) Elem(i int) Value {
+       panic("open array value element");
+       return nil
+}
+
+type FixedArrayValueStruct struct {
+       data    Addr;
+       typ     Type;
+       len     int;
+       elemtype        Type;
+       elemsize        uint64;
+}
+
+func (v *FixedArrayValueStruct) Kind() int {
+       return ArrayKind
+}
+
+func (v *FixedArrayValueStruct) Type() Type {
+       return v.typ
+}
+
+func (v *FixedArrayValueStruct) Open() bool {
+       return false
+}
+
+func (v *FixedArrayValueStruct) Len() int {
+       return v.len
+}
+
+func (v *FixedArrayValueStruct) Elem(i int) Value {
+       return NewValueAddr(v.elemtype, v.data + uint64(i) * v.elemsize);
+       return nil
+}
+
+func ArrayCreator(typ Type, addr Addr) Value {
+       arraytype := typ.(ArrayType);
+       if arraytype.Open() {
+               v := new(OpenArrayValueStruct);
+               v.data = addr;
+               v.typ = typ;
+               return v;
+       }
+       v := new(FixedArrayValueStruct);
+       v.data = addr;
+       v.typ = typ;
+       v.elemtype = arraytype.Elem();
+       v.elemsize = arraytype.Len();
+       return v;
+}
+
+// -- Map      TODO: finish and test
+
+export type MapValue interface {
+       Kind()  int;
+       Type()  Type;
+       Len()   int;
+       Elem(key Value) Value;
+}
+
+type MapValueStruct struct {
+       data    Addr;
+       typ     Type;
+       len     int;
+}
+
+func (v *MapValueStruct) Kind() int {
+       return MapKind
+}
+
+func (v *MapValueStruct) Type() Type {
+       return v.typ
+}
+
+func (v *MapValueStruct) Len() int {
+       return v.len    // TODO: probably want this to be dynamic
+}
+
+func (v *MapValueStruct) Elem(key Value) Value {
+       panic("map value element");
+       return nil
+}
+
+func MapCreator(typ Type, addr Addr) Value {
+       arraytype := typ.(MapType);
+       v := new(MapValueStruct);
+       v.data = addr;
+       v.typ = typ;
+       return v;
+}
+
+// -- Chan
+
+export type ChanValue interface {
+       Kind()  int;
+       Type()  Type;
+}
+
+type ChanValueStruct struct {
+       data    Addr;
+       typ     Type;
+       len     int;
+}
+
+func (v *ChanValueStruct) Kind() int {
+       return ChanKind
+}
+
+func (v *ChanValueStruct) Type() Type {
+       return v.typ
+}
+
+func ChanCreator(typ Type, addr Addr) Value {
+       v := new(ChanValueStruct);
+       v.data = addr;
+       v.typ = typ;
+       return v;
+}
+
+// -- Struct
+
+export type StructValue interface {
+       Kind()  int;
+       Type()  Type;
+       Len()   int;
+       Field(i int)    Value;
+}
+
+type StructValueStruct struct {
+       typ     Type;
+       field   *[]Value;
+}
+
+func (v *StructValueStruct) Kind() int {
+       return StructKind
+}
+
+func (v *StructValueStruct) Type() Type {
+       return v.typ
+}
+
+func (v *StructValueStruct) Len() int {
+       return len(v.field)
+}
+
+func (v *StructValueStruct) Field(i int) Value {
+       return v.field[i]
+}
+
+func StructCreator(typ Type, addr Addr) Value {
+       t := typ.(StructType);
+       v := new(StructValueStruct);
+       nfield := t.Len();
+       v.field = new([]Value, nfield);
+       for i := 0; i < nfield; i++ {
+               name, ftype, offset := t.Field(i);
+               v.field[i] = NewValueAddr(ftype, addr + offset);
+       }
+       v.typ = typ;
+       return v;
+}
+
+// -- Interface
+
+export type InterfaceValue interface {
+       Kind()  int;
+       Type()  Type;
+}
+
+type InterfaceValueInterface struct {
+       data    Addr;
+       typ     Type;
+}
+
+func (v *InterfaceValueInterface) Kind() int {
+       return InterfaceKind
+}
+
+func (v *InterfaceValueInterface) Type() Type {
+       return v.typ
+}
+
+func InterfaceCreator(typ Type, addr Addr) Value {
+       v := new(InterfaceValueInterface);
+       v.data = addr;
+       v.typ = typ;
+       return v;
+}
+
+// -- Func
+
+export type FuncValue interface {
+       Kind()  int;
+       Type()  Type;
+}
+
+type FuncValueFunc struct {
+       data    Addr;
+       typ     Type;
+}
+
+func (v *FuncValueFunc) Kind() int {
+       return FuncKind
+}
+
+func (v *FuncValueFunc) Type() Type {
+       return v.typ
+}
+
+func FuncCreator(typ Type, addr Addr) Value {
+       v := new(FuncValueFunc);
+       v.data = addr;
+       v.typ = typ;
+       return v;
+}
+
+var creator *map[int] Creator
+
+func init() {
+       creator = new(map[int] Creator);
+       creator[Int8Kind] = &Int8Creator;
+       creator[Int16Kind] = &Int16Creator;
+       creator[Int32Kind] = &Int32Creator;
+       creator[Int64Kind] = &Int64Creator;
+       creator[Uint8Kind] = &Uint8Creator;
+       creator[Uint16Kind] = &Uint16Creator;
+       creator[Uint32Kind] = &Uint32Creator;
+       creator[Uint64Kind] = &Uint64Creator;
+       creator[Float32Kind] = &Float32Creator;
+       creator[Float64Kind] = &Float64Creator;
+       creator[Float80Kind] = &Float80Creator;
+       creator[StringKind] = &StringCreator;
+       creator[PtrKind] = &PtrCreator;
+       creator[ArrayKind] = &ArrayCreator;
+       creator[MapKind] = &MapCreator;
+       creator[ChanKind] = &ChanCreator;
+       creator[StructKind] = &StructCreator;
+       creator[InterfaceKind] = &InterfaceCreator;
+       creator[FuncKind] = &FuncCreator;
+}
+
+func NewValueAddr(typ Type, addr Addr) Value {
+       c, ok := creator[typ.Kind()];
+       if !ok {
+               panicln("no creator for type" , typ.Kind());
+       }
+       return c(typ, addr);
+}
+
+// TODO: do this better
+export func NewInitValue(typ Type) Value {
+       size := typ.Size();
+       if size == 0 {
+               size = 1;
+       }
+       data := new([]uint8, size);
+       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
+}