tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

Wasm: make (runtime.alloc) fails even after calling to wasm_memory_grow

Open antJack opened this issue 5 years ago • 2 comments

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

antJack avatar Feb 21 '21 02:02 antJack

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.

aykevl avatar Mar 05 '21 13:03 aykevl

@antJack mind closing this out or letting us know what's still broke?

codefromthecrypt avatar Sep 07 '22 09:09 codefromthecrypt

Closing. We fixed the the issue and the original code was unsafe anyway.

dgryski avatar Jan 31 '23 01:01 dgryski