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
|
// ptrToString returns a string from WebAssembly compatible numeric types
|
||||||
// representing its pointer and length.
|
// representing its pointer and length.
|
||||||
func ptrToString(ptr uint32, size uint32) (ret string) {
|
func ptrToString(ptr uint32, size uint32) string {
|
||||||
// Here, we want to get a string represented by the ptr and size. If we
|
// Get a slice view of the underlying bytes in the stream. We use SliceHeader, not StringHeader
|
||||||
// wanted a []byte, we'd use reflect.SliceHeader instead.
|
// as it allows us to fix the capacity to what was allocated.
|
||||||
strHdr := (*reflect.StringHeader)(unsafe.Pointer(&ret))
|
return *(*string)(unsafe.Pointer(&reflect.SliceHeader{
|
||||||
strHdr.Data = uintptr(ptr)
|
Data: uintptr(ptr),
|
||||||
strHdr.Len = uintptr(size)
|
Len: uintptr(size), // Tinygo requires these as uintptrs even if they are int fields.
|
||||||
return
|
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
|
// stringToPtr returns a pointer and size pair for the given string in a way
|
||||||
|
|||||||
BIN
examples/allocation/tinygo/testdata/greet.wasm
vendored
BIN
examples/allocation/tinygo/testdata/greet.wasm
vendored
Binary file not shown.
@@ -15,7 +15,7 @@ import (
|
|||||||
// loggerFactory implements experimental.FunctionListenerFactory to log all function calls to the console.
|
// loggerFactory implements experimental.FunctionListenerFactory to log all function calls to the console.
|
||||||
type loggerFactory struct{}
|
type loggerFactory struct{}
|
||||||
|
|
||||||
// Size implements the same method as documented on api.Memory.
|
// NewListener implements the same method as documented on experimental.FunctionListener.
|
||||||
func (f *loggerFactory) NewListener(fnd experimental.FunctionDefinition) experimental.FunctionListener {
|
func (f *loggerFactory) NewListener(fnd experimental.FunctionDefinition) experimental.FunctionListener {
|
||||||
return &logger{funcName: []byte(fnd.ModuleName() + "." + funcName(fnd))}
|
return &logger{funcName: []byte(fnd.ModuleName() + "." + funcName(fnd))}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user