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:
@@ -80,30 +80,33 @@ func TestNewHostModule(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m, e := NewHostModule(tc.moduleName, tc.goFuncs)
|
||||
require.NoError(t, e)
|
||||
|
||||
// `require.Equal(t, tc.expected, m)` fails reflect pointers don't match, so brute compare:
|
||||
require.Equal(t, tc.expected.TypeSection, m.TypeSection)
|
||||
require.Equal(t, tc.expected.ImportSection, m.ImportSection)
|
||||
require.Equal(t, tc.expected.FunctionSection, m.FunctionSection)
|
||||
require.Equal(t, tc.expected.TableSection, m.TableSection)
|
||||
require.Equal(t, tc.expected.MemorySection, m.MemorySection)
|
||||
require.Equal(t, tc.expected.GlobalSection, m.GlobalSection)
|
||||
require.Equal(t, tc.expected.ExportSection, m.ExportSection)
|
||||
require.Equal(t, tc.expected.StartSection, m.StartSection)
|
||||
require.Equal(t, tc.expected.ElementSection, m.ElementSection)
|
||||
require.Nil(t, m.CodeSection) // Host functions are implemented in Go, not Wasm!
|
||||
require.Equal(t, tc.expected.DataSection, m.DataSection)
|
||||
require.Equal(t, tc.expected.NameSection, m.NameSection)
|
||||
|
||||
// Special case because reflect.Value can't be compared with Equals
|
||||
require.Equal(t, len(tc.expected.HostFunctionSection), len(m.HostFunctionSection))
|
||||
for i := range tc.expected.HostFunctionSection {
|
||||
require.Equal(t, (*tc.expected.HostFunctionSection[i]).Type(), (*m.HostFunctionSection[i]).Type())
|
||||
}
|
||||
requireHostModuleEquals(t, tc.expected, m)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func requireHostModuleEquals(t *testing.T, expected, actual *Module) {
|
||||
// `require.Equal(t, expected, actual)` fails reflect pointers don't match, so brute compare:
|
||||
require.Equal(t, expected.TypeSection, actual.TypeSection)
|
||||
require.Equal(t, expected.ImportSection, actual.ImportSection)
|
||||
require.Equal(t, expected.FunctionSection, actual.FunctionSection)
|
||||
require.Equal(t, expected.TableSection, actual.TableSection)
|
||||
require.Equal(t, expected.MemorySection, actual.MemorySection)
|
||||
require.Equal(t, expected.GlobalSection, actual.GlobalSection)
|
||||
require.Equal(t, expected.ExportSection, actual.ExportSection)
|
||||
require.Equal(t, expected.StartSection, actual.StartSection)
|
||||
require.Equal(t, expected.ElementSection, actual.ElementSection)
|
||||
require.Nil(t, actual.CodeSection) // Host functions are implemented in Go, not Wasm!
|
||||
require.Equal(t, expected.DataSection, actual.DataSection)
|
||||
require.Equal(t, expected.NameSection, actual.NameSection)
|
||||
|
||||
// Special case because reflect.Value can't be compared with Equals
|
||||
require.Equal(t, len(expected.HostFunctionSection), len(actual.HostFunctionSection))
|
||||
for i := range expected.HostFunctionSection {
|
||||
require.Equal(t, (*expected.HostFunctionSection[i]).Type(), (*actual.HostFunctionSection[i]).Type())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewHostModule_Errors(t *testing.T) {
|
||||
t.Run("Adds export name to error message", func(t *testing.T) {
|
||||
_, err := NewHostModule("test", map[string]interface{}{"fn": "hello"})
|
||||
|
||||
Reference in New Issue
Block a user