Runtime.NewModule -> InstantiateModule and adds ModuleBuilder (#349)

This reverts `Runtime.NewModule` back to `InstantiateModule` as it calls
more attention to the registration aspect of it, and also makes a chain
of `NewXX` more clear. This is particularly helpful as this change
introduces `ModuleBuilder` which is created by `NewModuleBuilder`.

`ModuleBuilder` is a way to define a WebAssembly 1.0 (20191205) in Go.
The first iteration allows setting the module name and exported
functions. The next PR will add globals.

Ex. Below defines and instantiates a module named "env" with one function:

```go
hello := func() {
	fmt.Fprintln(stdout, "hello!")
}
_, err := r.NewModuleBuilder("env").ExportFunction("hello", hello).InstantiateModule()
```

If the same module may be instantiated multiple times, it is more efficient to separate steps. Ex.

```go
env, err := r.NewModuleBuilder("env").ExportFunction("get_random_string", getRandomString).Build()

_, err := r.InstantiateModule(env.WithName("env.1"))
_, err := r.InstantiateModule(env.WithName("env.2"))
```

Note: Builder methods do not return errors, to allow chaining. Any validation errors are deferred until Build.
Note: Insertion order is not retained. Anything defined by this builder is sorted lexicographically on Build.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2022-03-09 10:39:13 +08:00
committed by GitHub
parent 1e4834612a
commit 50d9fa58a1
22 changed files with 443 additions and 163 deletions

View File

@@ -19,7 +19,7 @@ func Test_WASI(t *testing.T) {
}
stdout := new(bytes.Buffer)
goFunc := func(ctx wasm.Module) {
random := func(ctx wasm.Module) {
// Write 8 random bytes to memory using WASI.
errno := randomGet(ctx, 0, 8)
require.Equal(t, wasi.ErrnoSuccess, errno)
@@ -33,11 +33,11 @@ func Test_WASI(t *testing.T) {
r := wazero.NewRuntime()
// Host functions can be exported as any module name, including the empty string.
env := &wazero.HostModuleConfig{Name: "", Functions: map[string]interface{}{"random": goFunc}}
_, err := r.NewHostModuleFromConfig(env)
_, err := r.NewModuleBuilder("").ExportFunction("random", random).Instantiate()
require.NoError(t, err)
// Configure WASI and implement the function to use it
we, err := r.NewHostModuleFromConfig(wazero.WASISnapshotPreview1())
we, err := r.InstantiateModule(wazero.WASISnapshotPreview1())
require.NoError(t, err)
randomGetFn := we.ExportedFunction("random_get")
@@ -50,7 +50,7 @@ func Test_WASI(t *testing.T) {
// The "random" function was imported as $random in Wasm. Since it was marked as the start
// function, it is invoked on instantiation. Ensure that worked: "random" was called!
_, err = r.NewModuleFromSource([]byte(`(module $wasi
_, err = r.InstantiateModuleFromSource([]byte(`(module $wasi
(import "wasi_snapshot_preview1" "random_get"
(func $wasi.random_get (param $buf i32) (param $buf_len i32) (result (;errno;) i32)))
(import "" "random" (func $random))