1
0
mirror of https://github.com/golang/go synced 2024-11-13 19:10:22 -07:00

Reflection values.

R=rsc
DELTA=206  (79 added, 25 deleted, 102 changed)
OCL=17652
CL=17669
This commit is contained in:
Rob Pike 2008-10-22 16:48:17 -07:00
parent 7dbee69b58
commit 34b8873722
3 changed files with 177 additions and 123 deletions

View File

@ -10,7 +10,7 @@ import (
func typedump(s string) { func typedump(s string) {
t := reflect.ParseTypeString("", s); 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) { func valuedump(s string) {
@ -45,12 +45,13 @@ func valuedump(s string) {
export type empty interface {} 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() { func main() {
var s string; var s string;
var t reflect.Type; var t reflect.Type;
if false{
typedump("int8"); typedump("int8");
typedump("int16"); typedump("int16");
typedump("int32"); 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; b int32}");
typedump("struct {a int8; b int8; c int8; d 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}"); typedump("struct {a int8; b int8; c int8; d int8; e int8; b int32}");
valuedump("int8"); valuedump("int8");
valuedump("int16"); valuedump("int16");
valuedump("int32"); 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; b int32}");
valuedump("struct {a int8; b int8; c int8; d 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}"); valuedump("struct {a int8; b int8; c int8; d int8; e int8; b int32}");
}
v := new(T); { var tmp = 123;
a, b := sys.reflect(v.(empty)); value := reflect.NewValue(tmp);
println(a, b); println(reflect.ValueToString(value));
typedump(b); }
{ 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()));
}
} }

View File

@ -12,7 +12,7 @@ import (
"strings"; "strings";
) )
export func TypeToString(typ Type) string export func TypeToString(typ Type, expand bool) string
export func ValueToString(val Value) string export func ValueToString(val Value) string
type HasFields interface { type HasFields interface {
@ -24,7 +24,7 @@ func TypeFieldsToString(t HasFields, sep string) string {
var str string; var str string;
for i := 0; i < t.Len(); i++ { for i := 0; i < t.Len(); i++ {
str1, typ, offset := t.Field(i); str1, typ, offset := t.Field(i);
str1 += " " + TypeToString(typ); str1 += " " + TypeToString(typ, false);
if i < t.Len() - 1 { if i < t.Len() - 1 {
str1 += sep + " "; str1 += sep + " ";
} }
@ -33,9 +33,9 @@ func TypeFieldsToString(t HasFields, sep string) string {
return str; return str;
} }
func TypeToString(typ Type) string { func TypeToString(typ Type, expand bool) string {
var str string; var str string;
if name := typ.Name(); name != "" { if name := typ.Name(); !expand && name != "" {
return name return name
} }
switch(typ.Kind()) { switch(typ.Kind()) {
@ -67,7 +67,7 @@ func TypeToString(typ Type) string {
return "string"; return "string";
case PtrKind: case PtrKind:
p := typ.(PtrType); p := typ.(PtrType);
return "*" + TypeToString(p.Sub()); return "*" + TypeToString(p.Sub(), false);
case ArrayKind: case ArrayKind:
a := typ.(ArrayType); a := typ.(ArrayType);
if a.Open() { if a.Open() {
@ -75,11 +75,11 @@ func TypeToString(typ Type) string {
} else { } else {
str = "[" + strings.ltoa(int64(a.Len())) + "]" str = "[" + strings.ltoa(int64(a.Len())) + "]"
} }
return str + TypeToString(a.Elem()); return str + TypeToString(a.Elem(), false);
case MapKind: case MapKind:
m := typ.(MapType); m := typ.(MapType);
str = "map[" + TypeToString(m.Key()) + "]"; str = "map[" + TypeToString(m.Key(), false) + "]";
return str + TypeToString(m.Elem()); return str + TypeToString(m.Elem(), false);
case ChanKind: case ChanKind:
c := typ.(ChanType); c := typ.(ChanType);
switch c.Dir() { switch c.Dir() {
@ -92,7 +92,7 @@ func TypeToString(typ Type) string {
default: default:
panicln("reflect.TypeToString: unknown chan direction"); panicln("reflect.TypeToString: unknown chan direction");
} }
return str + TypeToString(c.Elem()); return str + TypeToString(c.Elem(), false);
case StructKind: case StructKind:
return "struct{" + TypeFieldsToString(typ, ";") + "}"; return "struct{" + TypeFieldsToString(typ, ";") + "}";
case InterfaceKind: case InterfaceKind:
@ -151,13 +151,13 @@ func ValueToString(val Value) string {
return val.(StringValue).Get(); return val.(StringValue).Get();
case PtrKind: case PtrKind:
v := val.(PtrValue); v := val.(PtrValue);
return TypeToString(typ) + "(" + integer(int64(v.Addr())) + ")"; return TypeToString(typ, false) + "(" + integer(int64(v.Indirect())) + ")";
case ArrayKind: case ArrayKind:
t := typ.(ArrayType); t := typ.(ArrayType);
v := val.(ArrayValue); v := val.(ArrayValue);
str += TypeToString(t); str += TypeToString(t, false);
str += "{"; str += "{";
for i := 0; i < v.Len(); i++ { for i := uint64(0); i < v.Len(); i++ {
if i > 0 { if i > 0 {
str += ", " str += ", "
} }
@ -168,7 +168,7 @@ func ValueToString(val Value) string {
case MapKind: case MapKind:
t := typ.(MapType); t := typ.(MapType);
v := val.(ArrayValue); v := val.(ArrayValue);
str = TypeToString(t); str = TypeToString(t, false);
str += "{"; str += "{";
str += "<can't iterate on maps>"; str += "<can't iterate on maps>";
str += "}"; str += "}";
@ -178,7 +178,7 @@ func ValueToString(val Value) string {
case StructKind: case StructKind:
t := typ.(StructType); t := typ.(StructType);
v := val.(StructValue); v := val.(StructValue);
str += TypeToString(t); // TODO: use the name? str += TypeToString(t, false);
str += "{"; str += "{";
for i := 0; i < v.Len(); i++ { for i := 0; i < v.Len(); i++ {
if i > 0 { if i > 0 {

View File

@ -11,6 +11,7 @@ import (
"reflect"; "reflect";
) )
type Addr uint64 // TODO: where are ptrint/intptr etc? type Addr uint64 // TODO: where are ptrint/intptr etc?
export type Value interface { export type Value interface {
@ -24,31 +25,20 @@ type Creator *(typ Type, addr Addr) Value
// Conversion functions, implemented in assembler // Conversion functions, implemented in assembler
func AddrToPtrAddr(Addr) *Addr func AddrToPtrAddr(Addr) *Addr
func PtrAddrToAddr(*Addr) Addr
func AddrToPtrInt8(Addr) *int8 func AddrToPtrInt8(Addr) *int8
func PtrInt8ToAddr(*int8) Addr
func AddrToPtrInt16(Addr) *int16 func AddrToPtrInt16(Addr) *int16
func PtrInt16ToAddr(*int16) Addr
func AddrToPtrInt32(Addr) *int32 func AddrToPtrInt32(Addr) *int32
func PtrInt32ToAddr(*int32) Addr
func AddrToPtrInt64(Addr) *int64 func AddrToPtrInt64(Addr) *int64
func PtrInt64ToAddr(*int64) Addr
func AddrToPtrUint8(Addr) *uint8 func AddrToPtrUint8(Addr) *uint8
func PtrUint8ToAddr(*uint8) Addr func PtrUint8ToAddr(*uint8) Addr
func AddrToPtrUint16(Addr) *uint16 func AddrToPtrUint16(Addr) *uint16
func PtrUint16ToAddr(*uint16) Addr
func AddrToPtrUint32(Addr) *uint32 func AddrToPtrUint32(Addr) *uint32
func PtrUint32ToAddr(*uint32) Addr
func AddrToPtrUint64(Addr) *uint64 func AddrToPtrUint64(Addr) *uint64
func PtrUint64ToAddr(*uint64) Addr func PtrUint64ToAddr(*uint64) Addr
func AddrToPtrFloat32(Addr) *float32 func AddrToPtrFloat32(Addr) *float32
func PtrFloat32ToAddr(*float32) Addr
func AddrToPtrFloat64(Addr) *float64 func AddrToPtrFloat64(Addr) *float64
func PtrFloat64ToAddr(*float64) Addr
func AddrToPtrFloat80(Addr) *float80 func AddrToPtrFloat80(Addr) *float80
func PtrFloat80ToAddr(*float80) Addr
func AddrToPtrString(Addr) *string func AddrToPtrString(Addr) *string
func PtrStringToAddr(*string) Addr
// -- Int8 // -- Int8
@ -60,7 +50,7 @@ export type Int8Value interface {
} }
type Int8ValueStruct struct { type Int8ValueStruct struct {
p *int8 addr Addr
} }
func (v *Int8ValueStruct) Kind() int { func (v *Int8ValueStruct) Kind() int {
@ -72,16 +62,16 @@ func (v *Int8ValueStruct) Type() Type {
} }
func (v *Int8ValueStruct) Get() int8 { func (v *Int8ValueStruct) Get() int8 {
return *v.p return *AddrToPtrInt8(v.addr)
} }
func (v *Int8ValueStruct) Put(i int8) { func (v *Int8ValueStruct) Put(i int8) {
*v.p = i *AddrToPtrInt8(v.addr) = i
} }
func Int8Creator(typ Type, addr Addr) Value { func Int8Creator(typ Type, addr Addr) Value {
v := new(Int8ValueStruct); v := new(Int8ValueStruct);
v.p = AddrToPtrInt8(addr); v.addr = addr;
return v; return v;
} }
@ -95,7 +85,7 @@ export type Int16Value interface {
} }
type Int16ValueStruct struct { type Int16ValueStruct struct {
p *int16 addr Addr
} }
func (v *Int16ValueStruct) Kind() int { func (v *Int16ValueStruct) Kind() int {
@ -107,16 +97,16 @@ func (v *Int16ValueStruct) Type() Type {
} }
func (v *Int16ValueStruct) Get() int16 { func (v *Int16ValueStruct) Get() int16 {
return *v.p return *AddrToPtrInt16(v.addr)
} }
func (v *Int16ValueStruct) Put(i int16) { func (v *Int16ValueStruct) Put(i int16) {
*v.p = i *AddrToPtrInt16(v.addr) = i
} }
func Int16Creator(typ Type, addr Addr) Value { func Int16Creator(typ Type, addr Addr) Value {
v := new(Int16ValueStruct); v := new(Int16ValueStruct);
v.p = AddrToPtrInt16(addr); v.addr = addr;
return v; return v;
} }
@ -130,7 +120,7 @@ export type Int32Value interface {
} }
type Int32ValueStruct struct { type Int32ValueStruct struct {
p *int32 addr Addr
} }
func (v *Int32ValueStruct) Type() Type { func (v *Int32ValueStruct) Type() Type {
@ -142,16 +132,16 @@ func (v *Int32ValueStruct) Kind() int {
} }
func (v *Int32ValueStruct) Get() int32 { func (v *Int32ValueStruct) Get() int32 {
return *v.p return *AddrToPtrInt32(v.addr)
} }
func (v *Int32ValueStruct) Put(i int32) { func (v *Int32ValueStruct) Put(i int32) {
*v.p = i *AddrToPtrInt32(v.addr) = i
} }
func Int32Creator(typ Type, addr Addr) Value { func Int32Creator(typ Type, addr Addr) Value {
v := new(Int32ValueStruct); v := new(Int32ValueStruct);
v.p = AddrToPtrInt32(addr); v.addr = addr;
return v; return v;
} }
@ -165,7 +155,7 @@ export type Int64Value interface {
} }
type Int64ValueStruct struct { type Int64ValueStruct struct {
p *int64 addr Addr
} }
func (v *Int64ValueStruct) Kind() int { func (v *Int64ValueStruct) Kind() int {
@ -177,16 +167,16 @@ func (v *Int64ValueStruct) Type() Type {
} }
func (v *Int64ValueStruct) Get() int64 { func (v *Int64ValueStruct) Get() int64 {
return *v.p return *AddrToPtrInt64(v.addr)
} }
func (v *Int64ValueStruct) Put(i int64) { func (v *Int64ValueStruct) Put(i int64) {
*v.p = i *AddrToPtrInt64(v.addr) = i
} }
func Int64Creator(typ Type, addr Addr) Value { func Int64Creator(typ Type, addr Addr) Value {
v := new(Int64ValueStruct); v := new(Int64ValueStruct);
v.p = AddrToPtrInt64(addr); v.addr = addr;
return v; return v;
} }
@ -200,7 +190,7 @@ export type Uint8Value interface {
} }
type Uint8ValueStruct struct { type Uint8ValueStruct struct {
p *uint8 addr Addr
} }
func (v *Uint8ValueStruct) Kind() int { func (v *Uint8ValueStruct) Kind() int {
@ -212,16 +202,16 @@ func (v *Uint8ValueStruct) Type() Type {
} }
func (v *Uint8ValueStruct) Get() uint8 { func (v *Uint8ValueStruct) Get() uint8 {
return *v.p return *AddrToPtrUint8(v.addr)
} }
func (v *Uint8ValueStruct) Put(i uint8) { func (v *Uint8ValueStruct) Put(i uint8) {
*v.p = i *AddrToPtrUint8(v.addr) = i
} }
func Uint8Creator(typ Type, addr Addr) Value { func Uint8Creator(typ Type, addr Addr) Value {
v := new(Uint8ValueStruct); v := new(Uint8ValueStruct);
v.p = AddrToPtrUint8(addr); v.addr = addr;
return v; return v;
} }
@ -235,7 +225,7 @@ export type Uint16Value interface {
} }
type Uint16ValueStruct struct { type Uint16ValueStruct struct {
p *uint16 addr Addr
} }
func (v *Uint16ValueStruct) Kind() int { func (v *Uint16ValueStruct) Kind() int {
@ -247,16 +237,16 @@ func (v *Uint16ValueStruct) Type() Type {
} }
func (v *Uint16ValueStruct) Get() uint16 { func (v *Uint16ValueStruct) Get() uint16 {
return *v.p return *AddrToPtrUint16(v.addr)
} }
func (v *Uint16ValueStruct) Put(i uint16) { func (v *Uint16ValueStruct) Put(i uint16) {
*v.p = i *AddrToPtrUint16(v.addr) = i
} }
func Uint16Creator(typ Type, addr Addr) Value { func Uint16Creator(typ Type, addr Addr) Value {
v := new(Uint16ValueStruct); v := new(Uint16ValueStruct);
v.p = AddrToPtrUint16(addr); v.addr = addr;
return v; return v;
} }
@ -270,7 +260,7 @@ export type Uint32Value interface {
} }
type Uint32ValueStruct struct { type Uint32ValueStruct struct {
p *uint32 addr Addr
} }
func (v *Uint32ValueStruct) Kind() int { func (v *Uint32ValueStruct) Kind() int {
@ -282,16 +272,16 @@ func (v *Uint32ValueStruct) Type() Type {
} }
func (v *Uint32ValueStruct) Get() uint32 { func (v *Uint32ValueStruct) Get() uint32 {
return *v.p return *AddrToPtrUint32(v.addr)
} }
func (v *Uint32ValueStruct) Put(i uint32) { func (v *Uint32ValueStruct) Put(i uint32) {
*v.p = i *AddrToPtrUint32(v.addr) = i
} }
func Uint32Creator(typ Type, addr Addr) Value { func Uint32Creator(typ Type, addr Addr) Value {
v := new(Uint32ValueStruct); v := new(Uint32ValueStruct);
v.p = AddrToPtrUint32(addr); v.addr = addr;
return v; return v;
} }
@ -305,7 +295,7 @@ export type Uint64Value interface {
} }
type Uint64ValueStruct struct { type Uint64ValueStruct struct {
p *uint64 addr Addr
} }
func (v *Uint64ValueStruct) Kind() int { func (v *Uint64ValueStruct) Kind() int {
@ -317,16 +307,16 @@ func (v *Uint64ValueStruct) Type() Type {
} }
func (v *Uint64ValueStruct) Get() uint64 { func (v *Uint64ValueStruct) Get() uint64 {
return *v.p return *AddrToPtrUint64(v.addr)
} }
func (v *Uint64ValueStruct) Put(i uint64) { func (v *Uint64ValueStruct) Put(i uint64) {
*v.p = i *AddrToPtrUint64(v.addr) = i
} }
func Uint64Creator(typ Type, addr Addr) Value { func Uint64Creator(typ Type, addr Addr) Value {
v := new(Uint64ValueStruct); v := new(Uint64ValueStruct);
v.p = AddrToPtrUint64(addr); v.addr = addr;
return v; return v;
} }
@ -340,7 +330,7 @@ export type Float32Value interface {
} }
type Float32ValueStruct struct { type Float32ValueStruct struct {
p *float32 addr Addr
} }
func (v *Float32ValueStruct) Kind() int { func (v *Float32ValueStruct) Kind() int {
@ -352,16 +342,16 @@ func (v *Float32ValueStruct) Type() Type {
} }
func (v *Float32ValueStruct) Get() float32 { func (v *Float32ValueStruct) Get() float32 {
return *v.p return *AddrToPtrFloat32(v.addr)
} }
func (v *Float32ValueStruct) Put(f float32) { func (v *Float32ValueStruct) Put(f float32) {
*v.p = f *AddrToPtrFloat32(v.addr) = f
} }
func Float32Creator(typ Type, addr Addr) Value { func Float32Creator(typ Type, addr Addr) Value {
v := new(Float32ValueStruct); v := new(Float32ValueStruct);
v.p = AddrToPtrFloat32(addr); v.addr = addr;
return v; return v;
} }
@ -375,7 +365,7 @@ export type Float64Value interface {
} }
type Float64ValueStruct struct { type Float64ValueStruct struct {
p *float64 addr Addr
} }
func (v *Float64ValueStruct) Kind() int { func (v *Float64ValueStruct) Kind() int {
@ -387,16 +377,16 @@ func (v *Float64ValueStruct) Type() Type {
} }
func (v *Float64ValueStruct) Get() float64 { func (v *Float64ValueStruct) Get() float64 {
return *v.p return *AddrToPtrFloat64(v.addr)
} }
func (v *Float64ValueStruct) Put(f float64) { func (v *Float64ValueStruct) Put(f float64) {
*v.p = f *AddrToPtrFloat64(v.addr) = f
} }
func Float64Creator(typ Type, addr Addr) Value { func Float64Creator(typ Type, addr Addr) Value {
v := new(Float64ValueStruct); v := new(Float64ValueStruct);
v.p = AddrToPtrFloat64(addr); v.addr = addr;
return v; return v;
} }
@ -410,7 +400,7 @@ export type Float80Value interface {
} }
type Float80ValueStruct struct { type Float80ValueStruct struct {
p *float80 addr Addr
} }
func (v *Float80ValueStruct) Kind() int { func (v *Float80ValueStruct) Kind() int {
@ -424,18 +414,18 @@ func (v *Float80ValueStruct) Type() Type {
/* /*
BUG: can't gen code for float80s BUG: can't gen code for float80s
func (v *Float80ValueStruct) Get() float80 { func (v *Float80ValueStruct) Get() float80 {
return *v.p return *AddrToPtrFloat80(v.addr)
return 0; return 0;
} }
func (v *Float80ValueStruct) Put(f float80) { func (v *Float80ValueStruct) Put(f float80) {
*v.p = f *AddrToPtrFloat80(v.addr) = f
} }
*/ */
func Float80Creator(typ Type, addr Addr) Value { func Float80Creator(typ Type, addr Addr) Value {
v := new(Float80ValueStruct); v := new(Float80ValueStruct);
v.p = AddrToPtrFloat80(addr); v.addr = addr;
return v; return v;
} }
@ -449,7 +439,7 @@ export type StringValue interface {
} }
type StringValueStruct struct { type StringValueStruct struct {
p *string addr Addr
} }
func (v *StringValueStruct) Kind() int { func (v *StringValueStruct) Kind() int {
@ -461,16 +451,16 @@ func (v *StringValueStruct) Type() Type {
} }
func (v *StringValueStruct) Get() string { func (v *StringValueStruct) Get() string {
return *v.p return *AddrToPtrString(v.addr)
} }
func (v *StringValueStruct) Put(s string) { func (v *StringValueStruct) Put(s string) {
*v.p = s *AddrToPtrString(v.addr) = s
} }
func StringCreator(typ Type, addr Addr) Value { func StringCreator(typ Type, addr Addr) Value {
v := new(StringValueStruct); v := new(StringValueStruct);
v.p = AddrToPtrString(addr); v.addr = addr;
return v; return v;
} }
@ -480,11 +470,11 @@ export type PtrValue interface {
Kind() int; Kind() int;
Sub() Value; Sub() Value;
Type() Type; Type() Type;
Addr() Addr; Indirect() Addr;
} }
type PtrValueStruct struct { type PtrValueStruct struct {
p *Addr; addr Addr;
typ Type; typ Type;
} }
@ -496,19 +486,16 @@ func (v *PtrValueStruct) Type() Type {
return v.typ return v.typ
} }
func (v *PtrValueStruct) Sub() Value { func (v *PtrValueStruct) Indirect() Addr {
return NewValueAddr(v.typ, *v.p); return *AddrToPtrAddr(v.addr)
} }
func (v *PtrValueStruct) Addr() Addr { func (v *PtrValueStruct) Sub() Value {
return *v.p return NewValueAddr(v.typ.(PtrType).Sub(), v.Indirect());
} }
func PtrCreator(typ Type, addr Addr) Value { func PtrCreator(typ Type, addr Addr) Value {
v := new(PtrValueStruct); return &PtrValueStruct{addr, typ};
v.p = AddrToPtrAddr(addr);
v.typ = typ;
return v;
} }
// -- Array TODO: finish and test // -- Array TODO: finish and test
@ -517,15 +504,23 @@ export type ArrayValue interface {
Kind() int; Kind() int;
Type() Type; Type() Type;
Open() bool; Open() bool;
Len() int; Len() uint64;
Elem(i int) Value; Elem(i uint64) Value;
} }
type OpenArrayValueStruct struct { type OpenArrayValueStruct struct {
data Addr; addr Addr;
typ Type; 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 { func (v *OpenArrayValueStruct) Kind() int {
return ArrayKind return ArrayKind
@ -539,21 +534,21 @@ func (v *OpenArrayValueStruct) Open() bool {
return true return true
} }
func (v *OpenArrayValueStruct) Len() int { func (v *OpenArrayValueStruct) Len() uint64 {
return v.len // TODO: probably want this to be dynamic return uint64(*AddrToPtrInt32(v.addr+8));
} }
func (v *OpenArrayValueStruct) Elem(i int) Value { func (v *OpenArrayValueStruct) Elem(i uint64) Value {
panic("open array value element"); base := *AddrToPtrAddr(v.addr);
return nil return NewValueAddr(v.elemtype, base + i * v.elemsize);
} }
type FixedArrayValueStruct struct { type FixedArrayValueStruct struct {
data Addr; addr Addr;
typ Type; typ Type;
len int;
elemtype Type; elemtype Type;
elemsize uint64; elemsize uint64;
len uint64;
} }
func (v *FixedArrayValueStruct) Kind() int { func (v *FixedArrayValueStruct) Kind() int {
@ -568,12 +563,12 @@ func (v *FixedArrayValueStruct) Open() bool {
return false return false
} }
func (v *FixedArrayValueStruct) Len() int { func (v *FixedArrayValueStruct) Len() uint64 {
return v.len return v.len
} }
func (v *FixedArrayValueStruct) Elem(i int) Value { func (v *FixedArrayValueStruct) Elem(i uint64) Value {
return NewValueAddr(v.elemtype, v.data + uint64(i) * v.elemsize); return NewValueAddr(v.elemtype, v.addr + i * v.elemsize);
return nil return nil
} }
@ -581,15 +576,18 @@ func ArrayCreator(typ Type, addr Addr) Value {
arraytype := typ.(ArrayType); arraytype := typ.(ArrayType);
if arraytype.Open() { if arraytype.Open() {
v := new(OpenArrayValueStruct); v := new(OpenArrayValueStruct);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
v.elemtype = arraytype.Elem();
v.elemsize = v.elemtype.Size();
return v; return v;
} }
v := new(FixedArrayValueStruct); v := new(FixedArrayValueStruct);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
v.elemtype = arraytype.Elem(); v.elemtype = arraytype.Elem();
v.elemsize = arraytype.Len(); v.elemsize = v.elemtype.Size();
v.len = arraytype.Len();
return v; return v;
} }
@ -603,7 +601,7 @@ export type MapValue interface {
} }
type MapValueStruct struct { type MapValueStruct struct {
data Addr; addr Addr;
typ Type; typ Type;
len int; len int;
} }
@ -628,7 +626,7 @@ func (v *MapValueStruct) Elem(key Value) Value {
func MapCreator(typ Type, addr Addr) Value { func MapCreator(typ Type, addr Addr) Value {
arraytype := typ.(MapType); arraytype := typ.(MapType);
v := new(MapValueStruct); v := new(MapValueStruct);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
return v; return v;
} }
@ -641,7 +639,7 @@ export type ChanValue interface {
} }
type ChanValueStruct struct { type ChanValueStruct struct {
data Addr; addr Addr;
typ Type; typ Type;
len int; len int;
} }
@ -656,7 +654,7 @@ func (v *ChanValueStruct) Type() Type {
func ChanCreator(typ Type, addr Addr) Value { func ChanCreator(typ Type, addr Addr) Value {
v := new(ChanValueStruct); v := new(ChanValueStruct);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
return v; return v;
} }
@ -671,6 +669,7 @@ export type StructValue interface {
} }
type StructValueStruct struct { type StructValueStruct struct {
addr Addr;
typ Type; typ Type;
field *[]Value; field *[]Value;
} }
@ -694,6 +693,7 @@ func (v *StructValueStruct) Field(i int) Value {
func StructCreator(typ Type, addr Addr) Value { func StructCreator(typ Type, addr Addr) Value {
t := typ.(StructType); t := typ.(StructType);
v := new(StructValueStruct); v := new(StructValueStruct);
v.addr = addr;
nfield := t.Len(); nfield := t.Len();
v.field = new([]Value, nfield); v.field = new([]Value, nfield);
for i := 0; i < nfield; i++ { for i := 0; i < nfield; i++ {
@ -712,7 +712,7 @@ export type InterfaceValue interface {
} }
type InterfaceValueInterface struct { type InterfaceValueInterface struct {
data Addr; addr Addr;
typ Type; typ Type;
} }
@ -726,7 +726,7 @@ func (v *InterfaceValueInterface) Type() Type {
func InterfaceCreator(typ Type, addr Addr) Value { func InterfaceCreator(typ Type, addr Addr) Value {
v := new(InterfaceValueInterface); v := new(InterfaceValueInterface);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
return v; return v;
} }
@ -739,7 +739,7 @@ export type FuncValue interface {
} }
type FuncValueFunc struct { type FuncValueFunc struct {
data Addr; addr Addr;
typ Type; typ Type;
} }
@ -753,7 +753,7 @@ func (v *FuncValueFunc) Type() Type {
func FuncCreator(typ Type, addr Addr) Value { func FuncCreator(typ Type, addr Addr) Value {
v := new(FuncValueFunc); v := new(FuncValueFunc);
v.data = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
return v; return v;
} }
@ -791,8 +791,16 @@ func NewValueAddr(typ Type, addr Addr) Value {
return c(typ, addr); return c(typ, addr);
} }
// TODO: do this better
export func NewInitValue(typ Type) Value { 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(); size := typ.Size();
if size == 0 { if size == 0 {
size = 1; size = 1;
@ -801,10 +809,14 @@ export func NewInitValue(typ Type) Value {
return NewValueAddr(typ, PtrUint8ToAddr(&data[0])); return NewValueAddr(typ, PtrUint8ToAddr(&data[0]));
} }
// TODO: do this better export type Empty interface {}
export func NewValue(e interface {}) Value {
// typestring, addr := sys.whathe(e); export func NewValue(e Empty) Value {
// typ := ParseTypeString(typestring); value, typestring := sys.reflect(e);
// return NewValueAddr(typ, addr); typ := ParseTypeString("", typestring);
return nil // 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));
} }