diff --git a/src/lib/fmt/fmt_test.go b/src/lib/fmt/fmt_test.go index c2dc9c107d2..ac5511a930f 100644 --- a/src/lib/fmt/fmt_test.go +++ b/src/lib/fmt/fmt_test.go @@ -27,12 +27,13 @@ type FmtTest struct { } // TODO(rsc): return []byte, but need to be able to pass as interface. -// func Bytes(s string) []byte { -// b := new([]byte, len(s)+1); -// syscall.StringToBytes(b, s); -// return b[0:len(s)]; -// } -func Bytes(s string) string { return s } +func Bytes(s string) *[]byte { + b := new([]byte, len(s)+1); + syscall.StringToBytes(b, s); + bp := new(*[]byte); + *bp = b[0:len(s)]; + return bp; +} const B32 uint32 = 1<<32 - 1 const B64 uint64 = 1<<64 - 1 diff --git a/src/lib/fmt/format.go b/src/lib/fmt/format.go index 4a5dea5f1fd..42d750dfc85 100644 --- a/src/lib/fmt/format.go +++ b/src/lib/fmt/format.go @@ -71,7 +71,7 @@ func (f *Fmt) init() { } export func New() *Fmt { - f := new(Fmt); + f := new(*Fmt); f.init(); return f; } diff --git a/src/lib/fmt/print.go b/src/lib/fmt/print.go index def4760c578..d32fd531d4a 100644 --- a/src/lib/fmt/print.go +++ b/src/lib/fmt/print.go @@ -46,7 +46,7 @@ type P struct { } func Printer() *P { - p := new(P); + p := new(*P); p.fmt = fmt.New(); return p; } @@ -253,10 +253,12 @@ func getString(v reflect.Value) (val string, ok bool) { switch v.Kind() { case reflect.StringKind: return v.(reflect.StringValue).Get(), true; + case reflect.PtrKind: + if val, ok := v.Interface().(*[]byte); ok { + return string(*val), true; + } } - if valb, okb := v.Interface().([]byte); okb { - return string(valb), true; - } + // TODO(rsc): check for Interface().([]byte) too. return "", false; } diff --git a/src/lib/reflect/all_test.go b/src/lib/reflect/all_test.go index df3ca648a27..d2e5bd07a2e 100644 --- a/src/lib/reflect/all_test.go +++ b/src/lib/reflect/all_test.go @@ -49,6 +49,9 @@ func typedump(s, t string) { func valuedump(s, t string) { typ := reflect.ParseTypeString("", s); v := reflect.NewInitValue(typ); + if v == nil { + panicln("valuedump", s); + } switch v.Kind() { case reflect.IntKind: v.(reflect.IntValue).Set(132); @@ -114,11 +117,11 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better typedump("**P.integer", "**P.integer"); typedump("[32]int32", "[32]int32"); typedump("[]int8", "[]int8"); - typedump("*map[string]int32", "*map[string]int32"); - typedump("*chan<-string", "*chan<-string"); - typedump("struct {c *chan *int32; d float32}", "struct{c *chan*int32; d float32}"); + typedump("map[string]int32", "map[string]int32"); + typedump("chan<-string", "chan<-string"); + typedump("struct {c chan *int32; d float32}", "struct{c chan*int32; d float32}"); typedump("*(a int8, b int32)", "*(a int8, b int32)"); - typedump("struct {c *(? *chan *P.integer, ? *int8)}", "struct{c *(*chan*P.integer, *int8)}"); + typedump("struct {c *(? chan *P.integer, ? *int8)}", "struct{c *(chan*P.integer, *int8)}"); typedump("struct {a int8; b int32}", "struct{a int8; b int32}"); typedump("struct {a int8; b int8; b int32}", "struct{a int8; b int8; b int32}"); typedump("struct {a int8; b int8; c int8; b int32}", "struct{a int8; b int8; c int8; b int32}"); @@ -145,11 +148,11 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better valuedump("**int8", "**int8(0)"); valuedump("[5]int32", "[5]int32{0, 0, 0, 0, 0}"); valuedump("**P.integer", "**P.integer(0)"); - valuedump("*map[string]int32", "*map[string]int32(0)"); - valuedump("*chan<-string", "*chan<-string(0)"); - valuedump("struct {c *chan *int32; d float32}", "struct{c *chan*int32; d float32}{*chan*int32(0), 0}"); + valuedump("map[string]int32", "map[string]int32{}"); + valuedump("chan<-string", "chan<-string"); + valuedump("struct {c chan *int32; d float32}", "struct{c chan*int32; d float32}{chan*int32, 0}"); valuedump("*(a int8, b int32)", "*(a int8, b int32)(0)"); - valuedump("struct {c *(? *chan *P.integer, ? *int8)}", "struct{c *(*chan*P.integer, *int8)}{*(*chan*P.integer, *int8)(0)}"); + valuedump("struct {c *(? chan *P.integer, ? *int8)}", "struct{c *(chan*P.integer, *int8)}{*(chan*P.integer, *int8)(0)}"); valuedump("struct {a int8; b int32}", "struct{a int8; b int32}{0, 0}"); valuedump("struct {a int8; b int8; b int32}", "struct{a int8; b int8; b int32}{0, 0, 0}"); @@ -173,7 +176,7 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better } { type C chan *T; // TODO: should not be necessary - var tmp = new(C); + var tmp = new(*C); value := reflect.NewValue(tmp); assert(reflect.ValueToString(value), "*reflect.C·all_test(@)"); } @@ -185,15 +188,14 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better // value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123); // assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.A·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); // } -// { -// type AA []int; -// tmp1 := [10]int{1,2,3,4,5,6,7,8,9,10}; // TODO: should not be necessary to use tmp1 -// var tmp *AA = &tmp1; -// value := reflect.NewValue(tmp); -// assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); -// value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123); -// assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); -// } + { + type AA []int; + var tmp = AA{1,2,3,4,5,6,7,8,9,10}; + value := reflect.NewValue(&tmp); // TODO: NewValue(tmp) too + assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"); + value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Set(123); + assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "reflect.AA·all_test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"); + } { var ip *int32; @@ -225,13 +227,13 @@ export func TestAll(tt *testing.T) { // TODO(r): wrap up better pt = t.(reflect.PtrType); assert(pt.Sub().String(), "int8"); - t = reflect.ParseTypeString("", "*struct {c *chan *int32; d float32}"); - assert(t.String(), "*struct {c *chan *int32; d float32}"); + t = reflect.ParseTypeString("", "*struct {c chan *int32; d float32}"); + assert(t.String(), "*struct {c chan *int32; d float32}"); pt = t.(reflect.PtrType); - assert(pt.Sub().String(), "struct {c *chan *int32; d float32}"); + assert(pt.Sub().String(), "struct {c chan *int32; d float32}"); st = pt.Sub().(reflect.StructType); name, typ, tag, offset = st.Field(0); - assert(typ.String(), "*chan *int32"); + assert(typ.String(), "chan *int32"); name, typ, tag, offset = st.Field(1); assert(typ.String(), "float32"); diff --git a/src/lib/reflect/tostring.go b/src/lib/reflect/tostring.go index 5e658a13041..eb5dc20c510 100644 --- a/src/lib/reflect/tostring.go +++ b/src/lib/reflect/tostring.go @@ -190,14 +190,15 @@ func ValueToString(val Value) string { return str; case MapKind: t := typ.(MapType); - v := val.(ArrayValue); + v := val.(MapValue); str = TypeToString(t, false); str += "{"; str += ""; str += "}"; return str; case ChanKind: - return "can't print chans yet"; + str = TypeToString(typ, false); + return str; case StructKind: t := typ.(StructType); v := val.(StructValue); diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go index 3fbfe110b9b..e187a54604c 100644 --- a/src/lib/reflect/type.go +++ b/src/lib/reflect/type.go @@ -175,7 +175,7 @@ func NewArrayTypeStruct(name, typestring string, open bool, len int, elem *StubT func (t *ArrayTypeStruct) Size() int { if t.open { - return ptrsize // open arrays are pointers to structures + return ptrsize*2 // open arrays are 2-word headers } return t.len * t.elem.Get().Size(); } @@ -207,12 +207,7 @@ type MapTypeStruct struct { } func NewMapTypeStruct(name, typestring string, key, elem *StubType) *MapTypeStruct { - return &MapTypeStruct{ Common{MapKind, typestring, name, 0}, key, elem} -} - -func (t *MapTypeStruct) Size() int { - panic("reflect.type: map.Size(): cannot happen"); - return 0 + return &MapTypeStruct{ Common{MapKind, typestring, name, ptrsize}, key, elem} } func (t *MapTypeStruct) Key() Type { @@ -243,12 +238,7 @@ type ChanTypeStruct struct { } func NewChanTypeStruct(name, typestring string, dir int, elem *StubType) *ChanTypeStruct { - return &ChanTypeStruct{ Common{ChanKind, typestring, name, 0}, elem, dir} -} - -func (t *ChanTypeStruct) Size() int { - panic("reflect.type: chan.Size(): cannot happen"); - return 0 + return &ChanTypeStruct{ Common{ChanKind, typestring, name, ptrsize}, elem, dir} } func (t *ChanTypeStruct) Dir() int { @@ -379,14 +369,14 @@ func (t *FuncTypeStruct) Out() StructType { } // Cache of expanded types keyed by type name. -var types *map[string] Type +var types map[string] Type // List of typename, typestring pairs -var typestring *map[string] string +var typestring map[string] string var initialized bool = false // Map of basic types to prebuilt StubTypes -var basicstub *map[string] *StubType +var basicstub map[string] *StubType var MissingStub *StubType; var DotDotDotStub *StubType; @@ -479,7 +469,7 @@ func init() { functiontype typename = name '.' name - doublequotedstring = + doublequotedstring = string in " "; escapes are \x00 (NUL) \n \t \" \\ fieldlist = [ field { [ ',' | ';' ] field } ] @@ -849,7 +839,7 @@ export func ParseTypeString(name, typestring string) Type { // If the typestring is empty, it represents (the type of) a nil interface value return NilInterface } - p := new(Parser); + p := new(*Parser); p.str = typestring; p.Next(); return p.Type(name).Get(); diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go index 473a308eeb5..1e566f44edc 100644 --- a/src/lib/reflect/value.go +++ b/src/lib/reflect/value.go @@ -46,6 +46,9 @@ func (c *Common) Addr() Addr { } func (c *Common) Interface() interface {} { + if uintptr(c.addr) == 0 { + panicln("reflect: address 0 for", c.typ.String()); + } return sys.unreflect(uint64(uintptr(*c.addr.(*Addr))), c.typ.String()); } @@ -622,7 +625,7 @@ func (v *FixedArrayValueStruct) Elem(i int) Value { func ArrayCreator(typ Type, addr Addr) Value { arraytype := typ.(ArrayType); if arraytype.Open() { - v := new(OpenArrayValueStruct); + v := new(*OpenArrayValueStruct); v.kind = ArrayKind; v.addr = addr; v.typ = typ; @@ -631,7 +634,7 @@ func ArrayCreator(typ Type, addr Addr) Value { v.array = addr.(*RuntimeArray); return v; } - v := new(FixedArrayValueStruct); + v := new(*FixedArrayValueStruct); v.kind = ArrayKind; v.addr = addr; v.typ = typ; @@ -793,7 +796,7 @@ func NewValueAddr(typ Type, addr Addr) 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?) + case FuncKind: // must be pointers, at least for now (TODO?) return nil; case ArrayKind: if typ.(ArrayType).Open() { @@ -821,7 +824,7 @@ export func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue { return nil } - array := new(RuntimeArray); + array := new(*RuntimeArray); size := typ.Elem().Size() * cap; if size == 0 { size = 1; @@ -871,13 +874,13 @@ export func NewValue(e interface {}) Value { p, ok := typecache[typestring]; if !ok { typ := ParseTypeString("", typestring); - p = new(Type); + p = new(*Type); *p = typ; typecache[typestring] = p; } // 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 := new(*uint64); *ap = value; return NewValueAddr(*p, ap.(Addr)); }