examples: switches tinygo example to use slice header (#524)
We get undefined behavior, at least in code that re-slices, unless capacity is set. This ensures the buffer under the string has a capacity set to the same length as its size. This also shows more explicitly the problems in TinyGo (ex some type mismatch you have to ignore until fixed). Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
15
examples/allocation/tinygo/testdata/greet.go
vendored
15
examples/allocation/tinygo/testdata/greet.go
vendored
@@ -56,13 +56,14 @@ func _greeting(ptr, size uint32) (ptrSize uint64) {
|
||||
|
||||
// ptrToString returns a string from WebAssembly compatible numeric types
|
||||
// representing its pointer and length.
|
||||
func ptrToString(ptr uint32, size uint32) (ret string) {
|
||||
// Here, we want to get a string represented by the ptr and size. If we
|
||||
// wanted a []byte, we'd use reflect.SliceHeader instead.
|
||||
strHdr := (*reflect.StringHeader)(unsafe.Pointer(&ret))
|
||||
strHdr.Data = uintptr(ptr)
|
||||
strHdr.Len = uintptr(size)
|
||||
return
|
||||
func ptrToString(ptr uint32, size uint32) string {
|
||||
// Get a slice view of the underlying bytes in the stream. We use SliceHeader, not StringHeader
|
||||
// as it allows us to fix the capacity to what was allocated.
|
||||
return *(*string)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(ptr),
|
||||
Len: uintptr(size), // Tinygo requires these as uintptrs even if they are int fields.
|
||||
Cap: uintptr(size), // ^^ See https://github.com/tinygo-org/tinygo/issues/1284
|
||||
}))
|
||||
}
|
||||
|
||||
// stringToPtr returns a pointer and size pair for the given string in a way
|
||||
|
||||
Reference in New Issue
Block a user