int ot, xt, n, isddd, dupok;
Sym *s, *s1, *s2;
Sig *a, *m;
- Type *t1, *tbase;
+ Type *t1, *tbase, *t2;
if(isideal(t))
fatal("dtypesym %T", t);
break;
case TARRAY:
- // ../../pkg/runtime/type.go:/ArrayType
- s1 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- if(t->bound < 0)
- ot = duintptr(s, ot, -1);
- else
+ if(t->bound >= 0) {
+ // ../../pkg/runtime/type.go:/ArrayType
+ s1 = dtypesym(t->type);
+ t2 = typ(TARRAY);
+ t2->type = t->type;
+ t2->bound = -1; // slice
+ s2 = dtypesym(t2);
+ ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
+ ot = dsymptr(s, ot, s1, 0);
+ ot = dsymptr(s, ot, s2, 0);
ot = duintptr(s, ot, t->bound);
+ } else {
+ // ../../pkg/runtime/type.go:/SliceType
+ s1 = dtypesym(t->type);
+ ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
+ ot = dsymptr(s, ot, s1, 0);
+ }
break;
case TCHAN:
t.Errorf("int16(-1).Int() returned %v", v.Int())
}
}
+
+func TestSlice(t *testing.T) {
+ xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
+ v := NewValue(xs).Slice(3, 5).Interface().([]int)
+ if len(v) != 2 || v[0] != 4 || v[1] != 5 {
+ t.Errorf("xs.Slice(3, 5) = %v", v)
+ }
+
+ xa := [7]int{10, 20, 30, 40, 50, 60, 70}
+ v = NewValue(&xa).Elem().Slice(2, 5).Interface().([]int)
+ if len(v) != 3 || v[0] != 30 || v[1] != 40 || v[2] != 50 {
+ t.Errorf("xa.Slice(2, 5) = %v", v)
+ }
+}
type arrayType struct {
commonType "array"
elem *runtime.Type
+ slice *runtime.Type
len uintptr
}
*(*string)(iv.addr) = x
}
-// BUG(rsc): Value.Slice should allow slicing arrays.
-
// Slice returns a slice of v.
-// It panics if v's Kind is not Slice.
+// It panics if v's Kind is not Array or Slice.
func (v Value) Slice(beg, end int) Value {
iv := v.internal()
- iv.mustBe(Slice)
+ if iv.kind != Array && iv.kind != Slice {
+ panic(&ValueError{"reflect.Value.Slice", iv.kind})
+ }
cap := v.Cap()
if beg < 0 || end < beg || end > cap {
panic("reflect.Value.Slice: slice index out of bounds")
}
- typ := iv.typ.toType()
+ var typ Type
+ var base uintptr
+ switch iv.kind {
+ case Array:
+ if iv.flag&flagAddr == 0 {
+ panic("reflect.Value.Slice: slice of unaddressable array")
+ }
+ typ = toType((*arrayType)(unsafe.Pointer(iv.typ)).slice)
+ base = uintptr(iv.addr)
+ case Slice:
+ typ = iv.typ.toType()
+ base = (*SliceHeader)(iv.addr).Data
+ }
s := new(SliceHeader)
- s.Data = uintptr((*SliceHeader)(iv.addr).Data) + uintptr(beg)*typ.Elem().Size()
+ s.Data = base + uintptr(beg)*typ.Elem().Size()
s.Len = end - beg
s.Cap = cap - beg
return valueFromAddr(iv.flag&flagRO, typ, unsafe.Pointer(s))
// ArrayType represents a fixed array type.
type ArrayType struct {
commonType
- elem *Type // array element type
- len uintptr
+ elem *Type // array element type
+ slice *Type // slice type
+ len uintptr
}
// SliceType represents a slice type.