Browse Source

reflect: add MakeSlice()

pull/3497/head
Damian Gryski 2 years ago
committed by Ayke
parent
commit
5cc5f11b58
  1. 34
      src/reflect/value.go
  2. 7
      src/reflect/value_test.go

34
src/reflect/value.go

@ -882,8 +882,40 @@ func (v Value) Convert(t Type) Value {
panic("unimplemented: (reflect.Value).Convert()")
}
//go:linkname slicePanic runtime.slicePanic
func slicePanic()
func MakeSlice(typ Type, len, cap int) Value {
panic("unimplemented: reflect.MakeSlice()")
if typ.Kind() != Slice {
panic("reflect.MakeSlice of non-slice type")
}
rtype := typ.(*rawType)
ulen := uint(len)
ucap := uint(cap)
maxSize := (^uintptr(0)) / 2
elementSize := rtype.elem().Size()
if elementSize > 1 {
maxSize /= uintptr(elementSize)
}
if ulen > ucap || ucap > uint(maxSize) {
slicePanic()
}
// This can't overflow because of the above checks.
size := uintptr(ucap) * elementSize
var slice sliceHeader
slice.cap = uintptr(ucap)
slice.len = uintptr(ulen)
slice.data = alloc(size, nil)
return Value{
typecode: rtype,
value: unsafe.Pointer(&slice),
flags: valueFlagExported,
}
}
func Zero(typ Type) Value {

7
src/reflect/value_test.go

@ -132,6 +132,13 @@ func TestSlice(t *testing.T) {
t.Errorf("s[%d]=%d, want %d", i, s[i], i*10)
}
}
refs = MakeSlice(TypeOf(s), 5, 10)
s = refs.Interface().([]int)
if len(s) != refs.Len() || cap(s) != refs.Cap() {
t.Errorf("len(s)=%v refs.Len()=%v cap(s)=%v refs.Cap()=%v", len(s), refs.Len(), cap(s), refs.Cap())
}
}
func equal[T comparable](a, b []T) bool {

Loading…
Cancel
Save