Skip to content

Commit

Permalink
compiler,reflect: add support for [...]T -> []T in reflect
Browse files Browse the repository at this point in the history
  • Loading branch information
dgryski authored and deadprogram committed Sep 10, 2023
1 parent f11731f commit 0042bf6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
2 changes: 2 additions & 0 deletions compiler/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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{
Expand Down
2 changes: 2 additions & 0 deletions src/reflect/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -427,6 +428,7 @@ type arrayType struct {
ptrTo *rawType
elem *rawType
arrayLen uintptr
slicePtr *rawType
}

type mapType struct {
Expand Down
43 changes: 39 additions & 4 deletions src/reflect/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()")
Expand Down

0 comments on commit 0042bf6

Please sign in to comment.