aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/reflect
diff options
context:
space:
mode:
authorDamian Gryski <[email protected]>2023-03-20 13:20:14 -0700
committerRon Evans <[email protected]>2023-09-10 13:05:18 +0200
commit0042bf62a5c40cd3005104c1b146a965fed3e605 (patch)
tree6a0da78bcd8f484ea1310d7212e64701c1b7b37f /src/reflect
parentf11731ff35efe573030896b499cfa8bd4d13e9dc (diff)
downloadtinygo-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.go2
-rw-r--r--src/reflect/value.go43
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()")