Commit 9a7332fb authored by Rob Pike's avatar Rob Pike

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
parent 88da39fe
...@@ -122,7 +122,7 @@ func (b *_StructBuilder) Array() { ...@@ -122,7 +122,7 @@ func (b *_StructBuilder) Array() {
pv := v.(reflect.PtrValue); pv := v.(reflect.PtrValue);
psubtype := pv.Type().(reflect.PtrType).Sub(); psubtype := pv.Type().(reflect.PtrType).Sub();
if pv.Get() == nil && psubtype.Kind() == reflect.ArrayKind { if pv.Get() == nil && psubtype.Kind() == reflect.ArrayKind {
av := reflect.NewOpenArrayValue(psubtype, 0, 8); av := reflect.NewSliceValue(psubtype, 0, 8);
pv.SetSub(av); pv.SetSub(av);
} }
} }
...@@ -148,7 +148,7 @@ func (b *_StructBuilder) Elem(i int) Builder { ...@@ -148,7 +148,7 @@ func (b *_StructBuilder) Elem(i int) Builder {
for n <= i { for n <= i {
n *= 2 n *= 2
} }
av1 := reflect.NewOpenArrayValue(av.Type(), av.Len(), n); av1 := reflect.NewSliceValue(av.Type(), av.Len(), n);
av1.CopyFrom(av, av.Len()); av1.CopyFrom(av, av.Len());
pv.SetSub(av1); pv.SetSub(av1);
av = av1; av = av1;
......
...@@ -270,7 +270,7 @@ func TestAll(tt *testing.T) { // TODO(r): wrap up better ...@@ -270,7 +270,7 @@ func TestAll(tt *testing.T) { // TODO(r): wrap up better
assert(typ.String(), "[]uint32"); assert(typ.String(), "[]uint32");
t = reflect.ParseTypeString("", "[]int32"); t = reflect.ParseTypeString("", "[]int32");
v := reflect.NewOpenArrayValue(t, 5, 10); v := reflect.NewSliceValue(t, 5, 10);
t1 := reflect.ParseTypeString("", "*[]int32"); t1 := reflect.ParseTypeString("", "*[]int32");
v1 := reflect.NewInitValue(t1); v1 := reflect.NewInitValue(t1);
if v1 == nil { panic("V1 is nil"); } if v1 == nil { panic("V1 is nil"); }
......
...@@ -81,7 +81,7 @@ func TypeToString(typ Type, expand bool) string { ...@@ -81,7 +81,7 @@ func TypeToString(typ Type, expand bool) string {
return "*" + TypeToString(p.Sub(), false); return "*" + TypeToString(p.Sub(), false);
case ArrayKind: case ArrayKind:
a := typ.(ArrayType); a := typ.(ArrayType);
if a.Open() { if a.IsSlice() {
str = "[]" str = "[]"
} else { } else {
str = "[" + strconv.Itoa64(int64(a.Len())) + "]" str = "[" + strconv.Itoa64(int64(a.Len())) + "]"
......
...@@ -165,7 +165,7 @@ func (t *ptrTypeStruct) Sub() Type { ...@@ -165,7 +165,7 @@ func (t *ptrTypeStruct) Sub() Type {
// -- Array // -- Array
type ArrayType interface { type ArrayType interface {
Open() bool; IsSlice() bool;
Len() int; Len() int;
Elem() Type; Elem() Type;
} }
...@@ -173,7 +173,7 @@ type ArrayType interface { ...@@ -173,7 +173,7 @@ type ArrayType interface {
type arrayTypeStruct struct { type arrayTypeStruct struct {
commonType; commonType;
elem *stubType; elem *stubType;
open bool; // otherwise fixed size isslice bool; // otherwise fixed array
len int; len int;
} }
...@@ -182,14 +182,14 @@ func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubT ...@@ -182,14 +182,14 @@ func newArrayTypeStruct(name, typestring string, open bool, len int, elem *stubT
} }
func (t *arrayTypeStruct) Size() int { func (t *arrayTypeStruct) Size() int {
if t.open { if t.isslice {
return ptrsize*2 // open arrays are 2-word headers return ptrsize*2 // open arrays are 2-word headers
} }
return t.len * t.elem.Get().Size(); return t.len * t.elem.Get().Size();
} }
func (t *arrayTypeStruct) Open() bool { func (t *arrayTypeStruct) IsSlice() bool {
return t.open return t.isslice
} }
func (t *arrayTypeStruct) Len() int { func (t *arrayTypeStruct) Len() int {
......
...@@ -544,11 +544,12 @@ func ptrCreator(typ Type, addr Addr) Value { ...@@ -544,11 +544,12 @@ func ptrCreator(typ Type, addr Addr) Value {
} }
// -- Array // -- Array
// Slices and arrays are represented by the same interface.
type ArrayValue interface { type ArrayValue interface {
Kind() int; Kind() int;
Type() Type; Type() Type;
Open() bool; IsSlice() bool;
Len() int; Len() int;
Cap() int; Cap() int;
Elem(i int) Value; Elem(i int) Value;
...@@ -560,114 +561,114 @@ type ArrayValue interface { ...@@ -560,114 +561,114 @@ type ArrayValue interface {
func copyArray(dst ArrayValue, src ArrayValue, n int); func copyArray(dst ArrayValue, src ArrayValue, n int);
/* /*
Run-time representation of open arrays looks like this: Run-time representation of slices looks like this:
struct Array { struct Slice {
byte* array; // actual data byte* array; // actual data
uint32 nel; // number of elements uint32 nel; // number of elements
uint32 cap; uint32 cap;
}; };
*/ */
type runtimeArray struct { type runtimeSlice struct {
data Addr; data Addr;
len uint32; len uint32;
cap uint32; cap uint32;
} }
type openArrayValueStruct struct { type sliceValueStruct struct {
commonValue; commonValue;
elemtype Type; elemtype Type;
elemsize int; elemsize int;
array *runtimeArray; slice *runtimeSlice;
} }
func (v *openArrayValueStruct) Open() bool { func (v *sliceValueStruct) IsSlice() bool {
return true return true
} }
func (v *openArrayValueStruct) Len() int { func (v *sliceValueStruct) Len() int {
return int(v.array.len); return int(v.slice.len);
} }
func (v *openArrayValueStruct) Cap() int { func (v *sliceValueStruct) Cap() int {
return int(v.array.cap); return int(v.slice.cap);
} }
func (v *openArrayValueStruct) SetLen(len int) { func (v *sliceValueStruct) SetLen(len int) {
if len > v.Cap() { 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) { func (v *sliceValueStruct) Set(src ArrayValue) {
if !src.Open() { if !src.IsSlice() {
panic("can't set from fixed array"); panic("can't set from fixed array");
} }
s := src.(*openArrayValueStruct); s := src.(*sliceValueStruct);
if !equalType(v.typ, s.typ) { 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 { func (v *sliceValueStruct) Elem(i int) Value {
data_uint := uintptr(v.array.data) + uintptr(i * v.elemsize); data_uint := uintptr(v.slice.data) + uintptr(i * v.elemsize);
return newValueAddr(v.elemtype, Addr(data_uint)); 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); copyArray(v, src, n);
} }
type fixedArrayValueStruct struct { type arrayValueStruct struct {
commonValue; commonValue;
elemtype Type; elemtype Type;
elemsize int; elemsize int;
len int; len int;
} }
func (v *fixedArrayValueStruct) Open() bool { func (v *arrayValueStruct) IsSlice() bool {
return false return false
} }
func (v *fixedArrayValueStruct) Len() int { func (v *arrayValueStruct) Len() int {
return v.len return v.len
} }
func (v *fixedArrayValueStruct) Cap() int { func (v *arrayValueStruct) Cap() int {
return v.len 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"); 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); data_uint := uintptr(v.addr) + uintptr(i * v.elemsize);
return newValueAddr(v.elemtype, Addr(data_uint)); return newValueAddr(v.elemtype, Addr(data_uint));
return nil return nil
} }
func (v *fixedArrayValueStruct) CopyFrom(src ArrayValue, n int) { func (v *arrayValueStruct) CopyFrom(src ArrayValue, n int) {
copyArray(v, src, n); copyArray(v, src, n);
} }
func arrayCreator(typ Type, addr Addr) Value { func arrayCreator(typ Type, addr Addr) Value {
arraytype := typ.(ArrayType); arraytype := typ.(ArrayType);
if arraytype.Open() { if arraytype.IsSlice() {
v := new(openArrayValueStruct); v := new(sliceValueStruct);
v.kind = ArrayKind; v.kind = ArrayKind;
v.addr = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
v.elemtype = arraytype.Elem(); v.elemtype = arraytype.Elem();
v.elemsize = v.elemtype.Size(); v.elemsize = v.elemtype.Size();
v.array = addr.(*runtimeArray); v.slice = addr.(*runtimeSlice);
return v; return v;
} }
v := new(fixedArrayValueStruct); v := new(arrayValueStruct);
v.kind = ArrayKind; v.kind = ArrayKind;
v.addr = addr; v.addr = addr;
v.typ = typ; v.typ = typ;
...@@ -832,7 +833,7 @@ func NewInitValue(typ Type) Value { ...@@ -832,7 +833,7 @@ func NewInitValue(typ Type) Value {
case FuncKind: // must be pointers, at least for now (TODO?) case FuncKind: // must be pointers, at least for now (TODO?)
return nil; return nil;
case ArrayKind: case ArrayKind:
if typ.(ArrayType).Open() { if typ.(ArrayType).IsSlice() {
return nil return nil
} }
} }
...@@ -844,20 +845,12 @@ func NewInitValue(typ Type) Value { ...@@ -844,20 +845,12 @@ func NewInitValue(typ Type) Value {
return newValueAddr(typ, Addr(&data[0])); return newValueAddr(typ, Addr(&data[0]));
} }
/* func NewSliceValue(typ ArrayType, len, cap int) ArrayValue {
Run-time representation of open arrays looks like this: if !typ.IsSlice() {
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() {
return nil return nil
} }
array := new(runtimeArray); array := new(runtimeSlice);
size := typ.Elem().Size() * cap; size := typ.Elem().Size() * cap;
if size == 0 { if size == 0 {
size = 1; size = 1;
...@@ -870,7 +863,7 @@ func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue { ...@@ -870,7 +863,7 @@ func NewOpenArrayValue(typ ArrayType, len, cap int) ArrayValue {
return newValueAddr(typ, Addr(array)); 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) { func copyArray(dst ArrayValue, src ArrayValue, n int) {
if n == 0 { if n == 0 {
return return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment