compiler,reflect: add support for [...]T -> []T in reflect

Этот коммит содержится в:
Damian Gryski 2023-03-20 13:20:14 -07:00 коммит произвёл Ron Evans
родитель f11731ff35
коммит 0042bf62a5
3 изменённых файлов: 43 добавлений и 4 удалений

Просмотреть файл

@ -218,6 +218,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
types.NewVar(token.NoPos, nil, "length", types.Typ[types.Uintptr]),
types.NewVar(token.NoPos, nil, "sliceOf", types.Typ[types.UnsafePointer]),
)
case *types.Map:
typeFieldTypes = append(typeFieldTypes,
@ -326,6 +327,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
c.getTypeCode(types.NewPointer(typ)), // ptrTo
c.getTypeCode(typ.Elem()), // elementType
llvm.ConstInt(c.uintptrType, uint64(typ.Len()), false), // length
c.getTypeCode(types.NewSlice(typ.Elem())), // slicePtr
}
case *types.Map:
typeFields = []llvm.Value{

Просмотреть файл

@ -29,6 +29,7 @@
// ptrTo *typeStruct
// elem *typeStruct // element type of the array
// arrayLen uintptr // length of the array (this is part of the type)
// slicePtr *typeStruct // pointer to []T type
// - map types (this is still missing the key and element types)
// meta uint8
// nmethods uint16 (0)
@ -427,6 +428,7 @@ type arrayType struct {
ptrTo *rawType
elem *rawType
arrayLen uintptr
slicePtr *rawType
}
type mapType struct {

Просмотреть файл

@ -555,8 +555,26 @@ func (v Value) Slice(i, j int) Value {
}
case Array:
// TODO(dgryski): can't do this yet because the resulting value needs type slice of v.elem(), not array of v.elem().
// need to be able to look up this "new" type so pointer equality of types still works
v.checkAddressable()
buf, length := buflen(v)
i, j := uintptr(i), uintptr(j)
if j < i || length < j {
slicePanic()
}
elemSize := v.typecode.underlying().elem().Size()
var hdr sliceHeader
hdr.len = j - i
hdr.cap = length - i
hdr.data = unsafe.Add(buf, i*elemSize)
sliceType := (*arrayType)(unsafe.Pointer(v.typecode.underlying())).slicePtr
return Value{
typecode: sliceType,
value: unsafe.Pointer(&hdr),
flags: v.flags,
}
case String:
i, j := uintptr(i), uintptr(j)
@ -604,9 +622,26 @@ func (v Value) Slice3(i, j, k int) Value {
}
case Array:
// TODO(dgryski): can't do this yet because the resulting value needs type v.elem(), not array of v.elem().
// need to be able to look up this "new" type so pointer equality of types still works
v.checkAddressable()
buf, length := buflen(v)
i, j, k := uintptr(i), uintptr(j), uintptr(k)
if j < i || k < j || length < k {
slicePanic()
}
elemSize := v.typecode.underlying().elem().Size()
var hdr sliceHeader
hdr.len = j - i
hdr.cap = k - i
hdr.data = unsafe.Add(buf, i*elemSize)
sliceType := (*arrayType)(unsafe.Pointer(v.typecode.underlying())).slicePtr
return Value{
typecode: sliceType,
value: unsafe.Pointer(&hdr),
flags: v.flags,
}
}
panic("unimplemented: (reflect.Value).Slice3()")