Im having issues getting memory.grow to work in golang api:
func writeStringToMemory(store *wasmtime.Store, mem wasmtime.Memory, s string) (int32, error) {
bytes := []byte(s)
buf := append(bytes, 0) // Null-terminate the string
allocSize := int32(len(buf))
frame := mem.UnsafeData(store)
// Calculate required memory in bytes
required := nextFreeOffset + allocSize
// Current memory size in bytes (1 page = 64KB = 65536 bytes)
const PageSize = 65536
currentMemSize := int32(mem.Size(store)) * PageSize
if required > currentMemSize {
// Calculate how many bytes we need to add
//bytesNeeded := required - currentMemSize
// Calculate the number of pages needed, rounding up
//pagesNeeded := uint64((bytesNeeded + PageSize - 1) / PageSize)
// Grow the memory by the required number of pages
_, err := mem.Grow(store, 1)
if err != nil {
return 0, fmt.Errorf("failed to grow memory: %v", err)
}
// Refresh the frame after growing
frame = mem.UnsafeData(store)
// Verify the growth was successful
newSize := int32(mem.Size(store)) * PageSize
if required > newSize {
return 0, fmt.Errorf("memory growth unsuccessful: required %d, available %d", required, newSize)
}
}
// Write the string bytes into memory at the current offset
copy(frame[nextFreeOffset:], buf)
// Store the current offset to return
currentOffset := nextFreeOffset
// Update the allocation pointer
nextFreeOffset += allocSize
return currentOffset, nil
}
the above code compiles etc however it crashes at runtime on mem.Grow(store, 1)
for debugging, the issue seems no matter how i do it the mem.grow fails its not clear to me how i assign string arguments as input into a function...can someone explain the correct way i would take a string and be able to pass it to a store. My current way seems wrong somehow:
strOffset2, err := writeStringToMemory(store, *mem, "second_argument")
if err != nil {
log.Fatalf("failed to write second string to memory: %v", err)
}
// Create arguments to pass in the call (e.g., argc, argv pointer)
args := []wasmtime.Val{
wasmtime.ValI32(2), // argc
wasmtime.ValI32(strOffset1), // argv1 pointer
wasmtime.ValI32(strOffset2), // argv2 pointer
}
_, err = startFunc.Call(store, args)
if err != nil {
log.Fatalf("failed to call '__main_argc_argv': %v", err)
}
I solved this and posted a minimal sample of how to fix it here : sample
Hey @Dean Hunter thanks for this (and posting your fix!) would you mind contributing the working code as an example?
I'm a bit at a loss on where exactly this should go, but maybe in wasmtime-go
? @Alex Crichton what do you think about that?
(and Merry Christmas/Happy Holidays to all!)
Victor Adossi said:
Hey Dean Hunter thanks for this (and posting your fix!) would you mind contributing the working code as an example?
I'm a bit at a loss on where exactly this should go, but maybe in
wasmtime-go
? Alex Crichton what do you think about that?(and Merry Christmas/Happy Holidays to all!)
Merry Christmas all! Just so i understand you want me to contribute the example on the wasmtime github right? Im happy to do so. Feel free to move this chat to any other channel instead also for others to find.
Yeah I was hoping for some feedback regarding where it should go! There's currently not an examples
folder in wasmtime-go
, but IMO it'd make a reasonable fit there :) maybe this could go in #wasmtime ?
[EDIT] Ah, maybe this can't be moved anymore
For passing strings to guests it's typically recommended that the guest exports a "malloc style" function so the host knows where to write the string. As for why Grow itself is failing here I'm not sure, can you paste the error message?
Last updated: Jan 24 2025 at 00:11 UTC