diff --git a/guest/handle/handle.go b/guest/handle/handle.go index e3e7f05..4fcadb9 100644 --- a/guest/handle/handle.go +++ b/guest/handle/handle.go @@ -40,11 +40,13 @@ func GetWaitingPod(uid string) api.WaitingPod { ptr, size := mem.StringToPtr(uid) // Wrap to avoid TinyGo 0.28: cannot use an exported function as value - mem.SendAndGetString(ptr, size, func(input_ptr, input_size, ptr uint32, limit mem.BufLimit) { - getWaitingPod(input_ptr, input_size, ptr, limit) + _bytes := mem.GetBytes(func(input_ptr uint32, limit mem.BufLimit) (len uint32) { + getWaitingPod(ptr, size, input_ptr, limit) }) + // Ensure uid string is not collected by the GC until after the function call runtime.KeepAlive(uid) + // WIP: Convert _bytes to api.WaitingPod? waitingPod := make([]api.WaitingPod, size) return waitingPod[0] } diff --git a/guest/internal/mem/mem.go b/guest/internal/mem/mem.go index a5e6181..7064088 100644 --- a/guest/internal/mem/mem.go +++ b/guest/internal/mem/mem.go @@ -104,8 +104,20 @@ func SendAndGetUint64(input_ptr uint32, input_size uint32, fn func(input_ptr, in return binary.LittleEndian.Uint64(readBuf) } -func SendAndGetString(input_ptr uint32, input_size uint32, fn func(input_ptr, input_size, ptr uint32, limit BufLimit)) string { - fn(input_ptr, input_size, uint32(readBufPtr), readBufLimit) - size := binary.LittleEndian.Uint32(readBuf) - return string(readBuf[size : size+binary.LittleEndian.Uint32(readBuf[size:])]) +func GetBytes(fn func(ptr uint32, limit BufLimit) (len uint32)) []byte { + size := fn(uint32(readBufPtr), readBufLimit) + if size == 0 { + return nil + } + + // If the function result fit in our read buffer, return it. + if size <= readBufLimit { + return readBuf[:size] + } + + // Resize buffer and get the result again if it's larger than our initial buffer + buf := make([]byte, size) + ptr := unsafe.Pointer(&buf[0]) + _ = fn(uint32(uintptr(ptr)), size) + return buf }