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
# 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
O1=\
type.$O\
cast_amd64.$O\
+ typestring.$O\
O2=\
value.$O\
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");
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);
}
// 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
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;
var str string;
switch(typ.Kind()) {
case MissingKind:
- return "missing";
+ return "$missing$";
case Int8Kind:
return "int8";
case Int16Kind:
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:
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(), ",") + ")";
}
// 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 {
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());
}
export func ExpandType(name string) Type
-//export var GlobalTypeStrings = sys.typestrings;
+export func typestrings() string // implemented in C; declared here
export const (
MissingKind = iota;
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;
// 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.
return PtrKind
}
-func (t *PtrTypeStruct) Size() int {
+func (t *PtrTypeStruct) Size() uint64 {
return ptrsize
}
// -- 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
}
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;
return MapKind
}
-func (t *MapTypeStruct) Size() int {
+func (t *MapTypeStruct) Size() uint64 {
panic("reflect.type: map.Size(): cannot happen");
return 0
}
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
}
// -- 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 {
}
// 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 {
// -- Interface
export type InterfaceType interface {
- Field(int) (name string, typ Type);
+ Field(int) (name string, typ Type, offset uint64);
Len() int;
}
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 {
return InterfaceKind
}
-func (t *InterfaceTypeStruct) Size() int {
+func (t *InterfaceTypeStruct) Size() uint64 {
return interfacesize
}
return FuncKind
}
-func (t *FuncTypeStruct) Size() int {
+func (t *FuncTypeStruct) Size() uint64 {
panic("reflect.type: func.Size(): cannot happen");
return 0
}
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;
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;
// 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();
}
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
// 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 {
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
}
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
}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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
+}