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() {
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;
......
......@@ -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"); }
......
......@@ -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())) + "]"
......
......@@ -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 {
......
......@@ -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
......
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