diff options
author | Damian Gryski <[email protected]> | 2023-03-20 13:20:14 -0700 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-09-10 13:05:18 +0200 |
commit | 0042bf62a5c40cd3005104c1b146a965fed3e605 (patch) | |
tree | 6a0da78bcd8f484ea1310d7212e64701c1b7b37f /src/reflect | |
parent | f11731ff35efe573030896b499cfa8bd4d13e9dc (diff) | |
download | tinygo-0042bf62a5c40cd3005104c1b146a965fed3e605.tar.gz tinygo-0042bf62a5c40cd3005104c1b146a965fed3e605.zip |
compiler,reflect: add support for [...]T -> []T in reflect
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/type.go | 2 | ||||
-rw-r--r-- | src/reflect/value.go | 43 |
2 files changed, 41 insertions, 4 deletions
diff --git a/src/reflect/type.go b/src/reflect/type.go index bd717af0d..39659cc62 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -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 { diff --git a/src/reflect/value.go b/src/reflect/value.go index 2499fca78..dc81fe66a 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -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()") |