Wasm: make (runtime.alloc) fails even after calling to wasm_memory_grow
Recently I used tinygo to compile my go file into wasm, the source file contains the following exported func:
//export malloc
func malloc(size uint) *byte {
buf := make([]byte, size)
return &buf[0]
}
compile command: (actually I use docker to do the compilation, and use the image: tinygo/tinygo-dev:latest)
tinygo build -o out.wasm -scheduler=none -target=wasi -wasm-abi=generic main.go
the outputed wasm contains the following code in its .wat file:
(memory (;0;) 2)
(export "memory" (memory 0))
which indicates that the memory size of the wasm is 2 page (2*64k), and the memory is exported
when I ran the outputed wasm file and do the following:
> call exported malloc with size=1k
success
> call exported malloc with size=1m
fail, since 1m > 2*64k
> call wasm_memory_grow to expand the exported memory of wasm to 100 page
success, the exported memory now contains 102 pages (=6684672 bytes)
> call malloc with size=1m
fail
so I wonder why the last call to malloc still fail ?
The first point I throught was that the runtime.alloc may not be able to adapt to or realize the heap size change caused by wasm_memory_grow (ps: the default gc module seems to be gc.extalloc?) and if it’s true, then what can we do to help the runtime gc module to adapt to the heap size change?
==========
Yet another question is that the -heap-size flags seems not working with -target=wasi
I tried adding -heap-size with -target=wasm, it does work, the outputed .wasm file does contain (memory (;0;) 10), yet introducing undesirable imported func likes: syscall/js.xxx
But when I switch to -target=wasi, the -heap-size flags seems not working, the outputed .wasm file only has (memory (;0;) 2) regardless the configured heap size
Maybe this commit is related: https://github.com/tinygo-org/tinygo/commit/d627208c48501e649a0c2a477f77556af1e35a99
This should be fixed in the latest dev branch, see https://github.com/tinygo-org/tinygo/pull/1567.
That said, please note that this is unsafe:
//export malloc
func malloc(size uint) *byte {
buf := make([]byte, size)
return &buf[0]
}
You are moving memory allocated in Go to outside Go. Therefore, the GC won't track it anymore and it might be freed at any time.
@antJack mind closing this out or letting us know what's still broke?
Closing. We fixed the the issue and the original code was unsafe anyway.