reflectlite: remove stringHeader

It's usually a better idea to use unsafe.String and such instead.
This commit is contained in:
Ayke van Laethem
2026-05-11 10:23:34 +02:00
committed by Ayke
parent 18033ebc36
commit 6682e41ab4
2 changed files with 17 additions and 43 deletions
+2 -8
View File
@@ -453,10 +453,7 @@ func rawStructFieldFromPointer(descriptor *structType, fieldType *RawType, data
data = unsafe.Add(data, 1) // C: data+1 data = unsafe.Add(data, 1) // C: data+1
tagLen := uintptr(*(*byte)(data)) tagLen := uintptr(*(*byte)(data))
data = unsafe.Add(data, 1) // C: data+1 data = unsafe.Add(data, 1) // C: data+1
tag = *(*string)(unsafe.Pointer(&stringHeader{ tag = unsafe.String((*byte)(data), tagLen)
data: data,
len: tagLen,
}))
} }
// Set the PkgPath to some (arbitrary) value if the package path is not // Set the PkgPath to some (arbitrary) value if the package path is not
@@ -930,10 +927,7 @@ func readStringZ(data unsafe.Pointer) string {
data = unsafe.Add(data, 1) // C: data++ data = unsafe.Add(data, 1) // C: data++
} }
return *(*string)(unsafe.Pointer(&stringHeader{ return unsafe.String((*byte)(start), len)
data: start,
len: len,
}))
} }
func (t *RawType) name() string { func (t *RawType) name() string {
+15 -35
View File
@@ -722,20 +722,12 @@ func (v Value) Slice(i, j int) Value {
case String: case String:
i, j := uintptr(i), uintptr(j) i, j := uintptr(i), uintptr(j)
str := *(*stringHeader)(v.value) str := *(*string)(v.value)
sliced := str[i:j]
if j < i || str.len < j {
slicePanic()
}
hdr := stringHeader{
data: unsafe.Add(str.data, i),
len: j - i,
}
return Value{ return Value{
typecode: v.typecode, typecode: v.typecode,
value: unsafe.Pointer(&hdr), value: unsafe.Pointer(&sliced),
flags: v.flags, flags: v.flags,
} }
} }
@@ -810,7 +802,7 @@ func (v Value) Len() int {
case Slice: case Slice:
return int((*sliceHeader)(v.value).len) return int((*sliceHeader)(v.value).len)
case String: case String:
return int((*stringHeader)(v.value).len) return len(*(*string)(v.value))
default: default:
panic(&ValueError{Method: "Len", Kind: v.Kind()}) panic(&ValueError{Method: "Len", Kind: v.Kind()})
} }
@@ -986,13 +978,10 @@ func (v Value) Index(i int) Value {
// Keeping valueFlagExported if set, but don't set valueFlagIndirect // Keeping valueFlagExported if set, but don't set valueFlagIndirect
// otherwise CanSet will return true for string elements (which is bad, // otherwise CanSet will return true for string elements (which is bad,
// strings are read-only). // strings are read-only).
s := *(*stringHeader)(v.value) s := *(*string)(v.value)
if uint(i) >= uint(s.len) {
panic("reflect: string index out of range")
}
return Value{ return Value{
typecode: uint8Type, typecode: uint8Type,
value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Add(s.data, i)))), value: unsafe.Pointer(uintptr(s[i])),
flags: v.flags & valueFlagExported, flags: v.flags & valueFlagExported,
} }
case Array: case Array:
@@ -1734,8 +1723,7 @@ const zerobufferLen = 32
func init() { func init() {
// 32 characters of zero bytes // 32 characters of zero bytes
zerobufferStr := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" zerobufferStr := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
s := (*stringHeader)(unsafe.Pointer(&zerobufferStr)) zerobuffer = unsafe.Pointer(unsafe.StringData(zerobufferStr))
zerobuffer = s.data
} }
func Zero(typ Type) Value { func Zero(typ Type) Value {
@@ -1786,19 +1774,11 @@ type sliceHeader struct {
cap uintptr cap uintptr
} }
// Like sliceHeader, this type is used internally to make sure pointer and // Verify SliceHeader size.
// non-pointer fields match those of actual strings.
type stringHeader struct {
data unsafe.Pointer
len uintptr
}
// Verify SliceHeader and StringHeader sizes.
// See https://github.com/tinygo-org/tinygo/pull/4156 // See https://github.com/tinygo-org/tinygo/pull/4156
// and https://github.com/tinygo-org/tinygo/issues/1284. // and https://github.com/tinygo-org/tinygo/issues/1284.
var ( var (
_ [unsafe.Sizeof([]byte{})]byte = [unsafe.Sizeof(sliceHeader{})]byte{} _ [unsafe.Sizeof([]byte{})]byte = [unsafe.Sizeof(sliceHeader{})]byte{}
_ [unsafe.Sizeof("")]byte = [unsafe.Sizeof(stringHeader{})]byte{}
) )
type ValueError struct { type ValueError struct {
@@ -1865,29 +1845,29 @@ func Copy(dst, src Value) int {
func buflen(v Value) (unsafe.Pointer, uintptr) { func buflen(v Value) (unsafe.Pointer, uintptr) {
var buf unsafe.Pointer var buf unsafe.Pointer
var len uintptr var length uintptr
switch v.typecode.Kind() { switch v.typecode.Kind() {
case Slice: case Slice:
hdr := (*sliceHeader)(v.value) hdr := (*sliceHeader)(v.value)
buf = hdr.data buf = hdr.data
len = hdr.len length = hdr.len
case Array: case Array:
if v.isIndirect() || v.typecode.Size() > unsafe.Sizeof(uintptr(0)) { if v.isIndirect() || v.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
buf = v.value buf = v.value
} else { } else {
buf = unsafe.Pointer(&v.value) buf = unsafe.Pointer(&v.value)
} }
len = uintptr(v.Len()) length = uintptr(v.Len())
case String: case String:
hdr := (*stringHeader)(v.value) s := *(*string)(v.value)
buf = hdr.data buf = unsafe.Pointer(unsafe.StringData(s))
len = hdr.len length = uintptr(len(s))
default: default:
// This shouldn't happen // This shouldn't happen
panic("reflect.Copy: not slice or array or string") panic("reflect.Copy: not slice or array or string")
} }
return buf, len return buf, length
} }
//go:linkname sliceGrow runtime.sliceGrow //go:linkname sliceGrow runtime.sliceGrow