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:
Crypt Keeper
2022-05-04 19:14:04 +08:00
committed by GitHub
parent 72f16d21eb
commit a47cb700ad
3 changed files with 9 additions and 8 deletions

View File

@@ -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

Binary file not shown.