From 9a7332fb5bb3287efa5420756c1b79f43937cc14 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 23 Jan 2009 15:56:04 -0800 Subject: [PATCH] remove the "open" concept from reflect and go with slices and arrays. the two still share an interface and Kind; that's probably ok but might be worth revisiting. R=rsc DELTA=74 (1 added, 8 deleted, 65 changed) OCL=23416 CL=23418 --- src/lib/json/struct.go | 4 +- src/lib/reflect/all_test.go | 2 +- src/lib/reflect/tostring.go | 2 +- src/lib/reflect/type.go | 10 ++--- src/lib/reflect/value.go | 87 +++++++++++++++++-------------------- 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/src/lib/json/struct.go b/src/lib/json/struct.go index 0d0c1476e7..f37ee461ef 100644 --- a/src/lib/json/struct.go +++ b/src/lib/json/struct.go @@ -122,7 +122,7 @@ func (b *_StructBuilder) Array() { pv := v.(reflect.PtrValue); psubtype := pv.Type().(reflect.PtrType).Sub(); if pv.Get() == nil && psubtype.Kind() == reflect.ArrayKind { - av := reflect.NewOpenArrayValue(psubtype, 0, 8); + av := reflect.NewSliceValue(psubtype, 0, 8); pv.SetSub(av); } } @@ -148,7 +148,7 @@ func (b *_StructBuilder) Elem(i int) Builder { for n <= i { n *= 2 } - av1 := reflect.NewOpenArrayValue(av.Type(), av.Len(), n); + av1 := reflect.NewSliceValue(av.Type(), av.Len(), n); av1.CopyFrom(av, av.Len()); pv.SetSub(av1); av = av1; diff --git a/src/lib/reflect/all_test.go b/src/lib/reflect/all_test.go index f991110a8d..a840fc8928 100644 --- a/src/lib/reflect/all_test.go +++ b/src/lib/reflect/all_test.go @@ -270,7 +270,7 @@ func TestAll(tt *testing.T) { // TODO(r): wrap up better assert(typ.String(), "[]uint32"); t = reflect.ParseTypeString("", "[]int32"); - v := reflect.NewOpenArrayValue(t, 5, 10); + v := reflect.NewSliceValue(t, 5, 10); t1 := reflect.ParseTypeString("", "*[]int32"); v1 := reflect.NewInitValue(t1); if v1 == nil { panic("V1 is nil"); } diff --git a/src/lib/reflect/tostring.go b/src/lib/reflect/tostring.go index 38d9d9135f..d317e1a68f 100644 --- a/src/lib/reflect/tostring.go +++ b/src/lib/reflect/tostring.go @@ -81,7 +81,7 @@ func TypeToString(typ Type, expand bool) string { return "*" + TypeToString(p.Sub(), false); case ArrayKind: a := typ.(ArrayType); - if a.Open() { + if a.IsSlice() { str = "[]" } else { str = "[" + strconv.Itoa64(int64(a.Len())) + "]" diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go index 1095ccb497..1dc95104d1 100644 --- a/src/lib/reflect/type.go +++ b/src/lib/reflect/type.go @@ -165,7 +165,7 @@ func (t *ptrTypeStruct) Sub() Type { // -- Array type ArrayType interface { - Open() bool; + IsSlice() bool; Len() int; Elem() Type; } @@ -173,7 +173,7 @@ type ArrayType interface { type arrayTypeStruct struct { commonType; elem *stubType; - open bool; // otherwise fixed size + isslice bool; // otherwise fixed array len int; } @@ -182,14 +182,14 @@ func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubT } func (t *arrayTypeStruct) Size() int { - if t.open { + if t.isslice { return ptrsize*2 // open arrays are 2-word headers } return t.len * t.elem.Get().Size(); } -func (t *arrayTypeStruct) Open() bool { - return t.open +func (t *arrayTypeStruct) IsSlice() bool { + return t.isslice } func (t *arrayTypeStruct) Len() int { diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go index 85fb38bc2c..8d60a8b9b2 100644 --- a/src/lib/reflect/value.go +++ b/src/lib/reflect/value.go @@ -544,11 +544,12 @@ func ptrCreator(typ Type, addr Addr) Value { } // -- Array +// Slices and arrays are represented by the same interface. type ArrayValue interface { Kind() int; Type() Type; - Open() bool; + IsSlice() bool; Len() int; Cap() int; Elem(i int) Value; @@ -560,114 +561,114 @@ type ArrayValue interface { func copyArray(dst ArrayValue, src ArrayValue, n int); /* - Run-time representation of open arrays looks like this: - struct Array { + Run-time representation of slices looks like this: + struct Slice { byte* array; // actual data uint32 nel; // number of elements uint32 cap; }; */ -type runtimeArray struct { +type runtimeSlice struct { data Addr; len uint32; cap uint32; } -type openArrayValueStruct struct { +type sliceValueStruct struct { commonValue; elemtype Type; elemsize int; - array *runtimeArray; + slice *runtimeSlice; } -func (v *openArrayValueStruct) Open() bool { +func (v *sliceValueStruct) IsSlice() bool { return true } -func (v *openArrayValueStruct) Len() int { - return int(v.array.len); +func (v *sliceValueStruct) Len() int { + return int(v.slice.len); } -func (v *openArrayValueStruct) Cap() int { - return int(v.array.cap); +func (v *sliceValueStruct) Cap() int { + return int(v.slice.cap); } -func (v *openArrayValueStruct) SetLen(len int) { +func (v *sliceValueStruct) SetLen(len int) { if len > v.Cap() { - panicln("reflect: OpenArrayValueStruct.SetLen", len, v.Cap()); + panicln("reflect: sliceValueStruct.SetLen", len, v.Cap()); } - v.array.len = uint32(len); + v.slice.len = uint32(len); } -func (v *openArrayValueStruct) Set(src ArrayValue) { - if !src.Open() { +func (v *sliceValueStruct) Set(src ArrayValue) { + if !src.IsSlice() { panic("can't set from fixed array"); } - s := src.(*openArrayValueStruct); + s := src.(*sliceValueStruct); if !equalType(v.typ, s.typ) { - panicln("incompatible array types in ArrayValue.Set()"); + panicln("incompatible types in ArrayValue.Set()"); } - *v.array = *s.array; + *v.slice = *s.slice; } -func (v *openArrayValueStruct) Elem(i int) Value { - data_uint := uintptr(v.array.data) + uintptr(i * v.elemsize); +func (v *sliceValueStruct) Elem(i int) Value { + data_uint := uintptr(v.slice.data) + uintptr(i * v.elemsize); return newValueAddr(v.elemtype, Addr(data_uint)); } -func (v *openArrayValueStruct) CopyFrom(src ArrayValue, n int) { +func (v *sliceValueStruct) CopyFrom(src ArrayValue, n int) { copyArray(v, src, n); } -type fixedArrayValueStruct struct { +type arrayValueStruct struct { commonValue; elemtype Type; elemsize int; len int; } -func (v *fixedArrayValueStruct) Open() bool { +func (v *arrayValueStruct) IsSlice() bool { return false } -func (v *fixedArrayValueStruct) Len() int { +func (v *arrayValueStruct) Len() int { return v.len } -func (v *fixedArrayValueStruct) Cap() int { +func (v *arrayValueStruct) Cap() int { return v.len } -func (v *fixedArrayValueStruct) SetLen(len int) { +func (v *arrayValueStruct) SetLen(len int) { } -func (v *fixedArrayValueStruct) Set(src ArrayValue) { +func (v *arrayValueStruct) Set(src ArrayValue) { panicln("can't set fixed array"); } -func (v *fixedArrayValueStruct) Elem(i int) Value { +func (v *arrayValueStruct) Elem(i int) Value { data_uint := uintptr(v.addr) + uintptr(i * v.elemsize); return newValueAddr(v.elemtype, Addr(data_uint)); return nil } -func (v *fixedArrayValueStruct) CopyFrom(src ArrayValue, n int) { +func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) { copyArray(v, src, n); } func arrayCreator(typ Type, addr Addr) Value { arraytype := typ.(ArrayType); - if arraytype.Open() { - v := new(openArrayValueStruct); + if arraytype.IsSlice() { + v := new(sliceValueStruct); v.kind = ArrayKind; v.addr = addr; v.typ = typ; v.elemtype = arraytype.Elem(); v.elemsize = v.elemtype.Size(); - v.array = addr.(*runtimeArray); + v.slice = addr.(*runtimeSlice); return v; } - v := new(fixedArrayValueStruct); + v := new(arrayValueStruct); v.kind = ArrayKind; v.addr = addr; v.typ = typ; @@ -832,7 +833,7 @@ func NewInitValue(typ Type) Value { case FuncKind: // must be pointers, at least for now (TODO?) return nil; case ArrayKind: - if typ.(ArrayType).Open() { + if typ.(ArrayType).IsSlice() { return nil } } @@ -844,20 +845,12 @@ func NewInitValue(typ Type) Value { return newValueAddr(typ, Addr(&data[0])); } -/* - Run-time representation of open arrays looks like this: - struct Array { - byte* array; // actual data - uint32 nel; // number of elements - uint32 cap; // allocated number of elements - }; -*/ -func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue { - if !typ.Open() { +func NewSliceValue(typ ArrayType, len, cap int) ArrayValue { + if !typ.IsSlice() { return nil } - array := new(runtimeArray); + array := new(runtimeSlice); size := typ.Elem().Size() * cap; if size == 0 { size = 1; @@ -870,7 +863,7 @@ func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue { return newValueAddr(typ, Addr(array)); } -// Works on both fixed and open arrays. +// Works on both slices and arrays func copyArray(dst ArrayValue, src ArrayValue, n int) { if n == 0 { return -- 2.48.1