Closed dimitropoulos closed 6 months ago
I wanted to also add that as far as I can tell this is not a duplicate of https://github.com/tetratelabs/wazero/issues/1059 since that issue is about exporting memory. Or, at least, I didn't see a way to do this in any file in the linked repo.
I do think the solution you need is the one outlined in https://github.com/tetratelabs/wazero/issues/1059#issuecomment-1502533911.
For an "env"
module that only creates and exports a memory that your module can import, you can have a look at:
https://github.com/wasilibs/go-re2/blob/f5c90396b5b6b752f7d1fb22563f44aaa052f292/internal/re2_wazero.go#L159-L161
This uses this module built with wat2wasm
and embed with go:embed
:
https://github.com/wasilibs/go-re2/blob/f5c90396b5b6b752f7d1fb22563f44aaa052f292/internal/re2_wazero.go#L31-L34
ohhh ok wow. thanks! it took me a while to understand that there are (intentionally) two different modules.
For anyone in the future, here's what I used:
(the doom-fizzbuzz.wasm
can be downloaded from the above link)
(the memory.wasm
is just a memory.wat
file with (module (memory (export "memory") 102 65536 shared))
compiled with the command in the comments before the embed)
package main
import (
"context"
_ "embed"
"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)
func js_milliseconds_since_start() uint32 {
return uint32(0)
}
func js_console_log(arg0 uint32, arg1 uint32) {
}
func js_draw_screen(arg0 uint32) {
}
func js_stdout(arg0 uint32, arg1 uint32) {
}
func js_stderr(arg0 uint32, arg1 uint32) {
}
//go:embed doom-fizzbuzz.wasm
var wasmBytes []byte
// wat2wasm memory.wat --output=memory.wasm --enable-threads
//
//go:embed memory.wasm
var memoryWasm []byte
func main() {
ctx := context.Background()
r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter().WithCoreFeatures(api.CoreFeaturesV2|experimental.CoreFeaturesThreads))
defer r.Close(ctx)
wasi_snapshot_preview1.MustInstantiate(ctx, r)
_, err := r.NewHostModuleBuilder("js").
NewFunctionBuilder().WithFunc(js_milliseconds_since_start).Export("js_milliseconds_since_start").
NewFunctionBuilder().WithFunc(js_console_log).Export("js_console_log").
NewFunctionBuilder().WithFunc(js_draw_screen).Export("js_draw_screen").
NewFunctionBuilder().WithFunc(js_stdout).Export("js_stdout").
NewFunctionBuilder().WithFunc(js_stderr).Export("js_stderr").
Instantiate(ctx)
if err != nil {
panic(err)
}
_, err = r.InstantiateWithConfig(ctx, memoryWasm, wazero.NewModuleConfig().WithName("env"))
if err != nil {
panic(err)
}
mod, err := r.Instantiate(ctx, wasmBytes)
if err != nil {
panic(err)
}
mainFunc := mod.ExportedFunction("main")
arg0 := uint64(1) // placeholder
arg1 := uint64(1) // placeholder
_, err = mainFunc.Call(ctx, arg0, arg1)
if err != nil {
panic(err)
}
}
thanks so much @ncruces!
Hi @dimitropoulos - for reference, I have had to switch from the static memory module approach to creating the module dynamically (being very simple, it's not too bad).
https://github.com/wasilibs/go-re2/commit/9f8aa894048abebc4f9d0fd48ce77415679ae5da
While I had initially thought virtual memory allocation has no limits, actually it can still be capped on systems with lower memory so had to make max memory dynamic.
Is your feature request related to a problem? Please describe. I have a wasm module that contains the field
And I can't figure out how I would use wazero to provide it.
In JavaScript you can just do something like
const memory = new WebAssembly.Memory({ initial: 1024 })
and provide it in the imports object.Describe the solution you'd like An way to provide the memory to the module.
Describe alternatives you've considered I've tried every combination I can think of using
NewFunctionBuilder
andWithFunc
returning a memory, but it doesn't seem to work.Additional context One real-world example of a wasm file that does this can be found on https://diekmann.github.io/wasm-fizzbuzz/doom. In my case I have others (compiled with emcc) that do the same thing. I believe this mechanism is used to pre-load the memory object before the wasm boots.