refactor: hostfunc module builder

This commit is contained in:
mathetake
2020-05-09 14:04:58 +09:00
parent 05c0096c52
commit 378c1a4dd7
12 changed files with 54 additions and 59 deletions

View File

@@ -23,8 +23,7 @@ Full examples can be found at: https://github.com/mathetake/gasm/tree/master/exa
func Test_fibonacci(t *testing.T) {
buf, _ := ioutil.ReadFile("wasm/fibonacci.wasm")
mod, _ := wasm.DecodeModule(bytes.NewBuffer(buf))
mod.BuildIndexSpaces(wasi.Modules)
vm, _ := wasm.NewVM(mod)
vm, _ := wasm.NewVM(mod, wasi.Modules)
for _, c := range []struct {
in, exp int32
@@ -45,11 +44,8 @@ func Test_fibonacci(t *testing.T) {
```golang
func Test_hostFunc(t *testing.T) {
buf, err := ioutil.ReadFile("wasm/host_func.wasm")
require.NoError(t, err)
mod, err := wasm.DecodeModule(bytes.NewBuffer(buf))
require.NoError(t, err)
buf, _ := ioutil.ReadFile("wasm/host_func.wasm")
mod, _ := wasm.DecodeModule(bytes.NewBuffer(buf))
var cnt uint64 // to be incremented as hostFunc is called
@@ -61,13 +57,9 @@ func Test_hostFunc(t *testing.T) {
})
}
builder := hostmodule.NewBuilderWith(wasi.Modules)
builder.MustAddFunction("env", "host_func", hostFunc)
err = mod.BuildIndexSpaces(builder.Done())
require.NoError(t, err)
vm, err := wasm.NewVM(mod)
require.NoError(t, err)
builder := hostfunc.NewModuleBuilderWith(wasi.Modules)
builder.MustSetFunction("env", "host_func", hostFunc)
vm, _ := wasm.NewVM(mod, builder.Done())
for _, exp := range []uint64{5, 10, 15} {
vm.ExecExportedFunction("call_host_func", exp)

View File

@@ -17,10 +17,7 @@ func Test_fibonacci(t *testing.T) {
mod, err := wasm.DecodeModule(bytes.NewBuffer(buf))
require.NoError(t, err)
err = mod.BuildIndexSpaces(wasi.Modules)
require.NoError(t, err)
vm, err := wasm.NewVM(mod)
vm, err := wasm.NewVM(mod, wasi.Modules)
require.NoError(t, err)
for _, c := range []struct {

View File

@@ -6,7 +6,7 @@ import (
"reflect"
"testing"
"github.com/mathetake/gasm/hostmodule"
"github.com/mathetake/gasm/hostfunc"
"github.com/mathetake/gasm/wasi"
"github.com/mathetake/gasm/wasm"
"github.com/stretchr/testify/require"
@@ -26,12 +26,9 @@ func Test_hostFunc(t *testing.T) {
})
}
builder := hostmodule.NewBuilderWith(wasi.Modules)
builder.MustAddFunction("env", "host_func", hostFunc)
err = mod.BuildIndexSpaces(builder.Done())
require.NoError(t, err)
vm, err := wasm.NewVM(mod)
builder := hostfunc.NewModuleBuilderWith(wasi.Modules)
builder.MustSetFunction("env", "host_func", hostFunc)
vm, err := wasm.NewVM(mod, builder.Done())
require.NoError(t, err)
for _, exp := range []uint64{5, 10, 15} {

View File

@@ -17,10 +17,7 @@ func Test_panic(t *testing.T) {
mod, err := wasm.DecodeModule(bytes.NewBuffer(buf))
require.NoError(t, err)
err = mod.BuildIndexSpaces(wasi.Modules)
require.NoError(t, err)
vm, err := wasm.NewVM(mod)
vm, err := wasm.NewVM(mod, wasi.Modules)
require.NoError(t, err)
defer func() {

View File

@@ -1,4 +1,4 @@
package hostmodule
package hostfunc
import (
"fmt"
@@ -7,27 +7,25 @@ import (
"github.com/mathetake/gasm/wasm"
)
type Builder struct {
type ModuleBuilder struct {
modules map[string]*wasm.Module
}
func NewBuilder() *Builder {
return &Builder{modules: map[string]*wasm.Module{}}
func NewModuleBuilder() *ModuleBuilder {
return &ModuleBuilder{modules: map[string]*wasm.Module{}}
}
func NewBuilderWith(in map[string]*wasm.Module) *Builder {
return &Builder{modules: in}
func NewModuleBuilderWith(in map[string]*wasm.Module) *ModuleBuilder {
return &ModuleBuilder{modules: in}
}
// TODO: support other types
func (m *Builder) MustAddFunction(modName, funcName string, fn func(machine *wasm.VirtualMachine) reflect.Value) {
if err := m.AddFunction(modName, funcName, fn); err != nil {
func (m *ModuleBuilder) MustSetFunction(modName, funcName string, fn func(machine *wasm.VirtualMachine) reflect.Value) {
if err := m.SetFunction(modName, funcName, fn); err != nil {
panic(err)
}
}
func (m *Builder) AddFunction(modName, funcName string, fn func(machine *wasm.VirtualMachine) reflect.Value) error {
func (m *ModuleBuilder) SetFunction(modName, funcName string, fn func(machine *wasm.VirtualMachine) reflect.Value) error {
mod, ok := m.modules[modName]
if !ok {
@@ -89,6 +87,6 @@ func getTypeOf(kind reflect.Kind) (wasm.ValueType, error) {
}
}
func (m *Builder) Done() map[string]*wasm.Module {
func (m *ModuleBuilder) Done() map[string]*wasm.Module {
return m.modules
}

View File

@@ -0,0 +1,3 @@
package hostfunc
// fixme:

View File

@@ -6,7 +6,7 @@ import (
"os"
"reflect"
"github.com/mathetake/gasm/hostmodule"
"github.com/mathetake/gasm/hostfunc"
"github.com/mathetake/gasm/wasm"
)
@@ -15,8 +15,8 @@ const wasiUnstableName = "wasi_unstable"
var Modules map[string]*wasm.Module
func init() {
b := hostmodule.NewBuilder()
b.MustAddFunction(wasiUnstableName, "fd_write", fd_write)
b := hostfunc.NewModuleBuilder()
b.MustSetFunction(wasiUnstableName, "fd_write", fd_write)
Modules = b.Done()
}

View File

@@ -79,8 +79,8 @@ func DecodeModule(r io.Reader) (*Module, error) {
return ret, nil
}
// BuildIndexSpaces build index spaces of the module with the given external modules
func (m *Module) BuildIndexSpaces(externModules map[string]*Module) error {
// buildIndexSpaces build index spaces of the module with the given external modules
func (m *Module) buildIndexSpaces(externModules map[string]*Module) error {
m.IndexSpace = new(ModuleIndexSpace)
// resolve imports

View File

@@ -30,7 +30,11 @@ type (
}
)
func NewVM(module *Module) (*VirtualMachine, error) {
func NewVM(module *Module, externModules map[string]*Module) (*VirtualMachine, error) {
if err := module.buildIndexSpaces(externModules); err != nil {
return nil, fmt.Errorf("build index space: %w", err)
}
vm := &VirtualMachine{
InnerModule: module,
OperandStack: NewVirtualMachineOperandStack(),

View File

@@ -161,5 +161,9 @@ func Test_brIf(t *testing.T) {
}
func Test_brAt(t *testing.T) {
// fixme:
}
func Test_brTable(t *testing.T) {
// fixme:
}

View File

@@ -1,6 +1,9 @@
package wasm
const initialStackHeight = 1024
const (
initialOperandStackHeight = 1024
initialLabelStackHeight = 10
)
func drop(vm *VirtualMachine) {
vm.OperandStack.Drop()
@@ -17,7 +20,7 @@ func selectOp(vm *VirtualMachine) {
func NewVirtualMachineOperandStack() *VirtualMachineOperandStack {
return &VirtualMachineOperandStack{
Stack: make([]uint64, initialStackHeight),
Stack: make([]uint64, initialOperandStackHeight),
SP: -1,
}
}
@@ -71,7 +74,7 @@ type Label struct {
func NewVirtualMachineLabelStack() *VirtualMachineLabelStack {
return &VirtualMachineLabelStack{
Stack: make([]*Label, initialStackHeight),
Stack: make([]*Label, initialLabelStackHeight),
SP: -1,
}
}

View File

@@ -8,44 +8,44 @@ import (
func TestVirtualMachineOperandStack(t *testing.T) {
s := NewVirtualMachineOperandStack()
assert.Equal(t, initialStackHeight, len(s.Stack))
assert.Equal(t, initialOperandStackHeight, len(s.Stack))
var exp uint64 = 10
s.Push(exp)
assert.Equal(t, exp, s.Pop())
// verify the length grows
for i := 0; i < initialStackHeight+1; i++ {
for i := 0; i < initialOperandStackHeight+1; i++ {
s.Push(uint64(i))
}
assert.True(t, len(s.Stack) > initialStackHeight)
assert.True(t, len(s.Stack) > initialOperandStackHeight)
// verify the length is not shortened
for i := 0; i < len(s.Stack); i++ {
_ = s.Pop()
}
assert.True(t, len(s.Stack) > initialStackHeight)
assert.True(t, len(s.Stack) > initialOperandStackHeight)
}
func TestVirtualMachineLabelStack(t *testing.T) {
s := NewVirtualMachineLabelStack()
assert.Equal(t, initialStackHeight, len(s.Stack))
assert.Equal(t, initialLabelStackHeight, len(s.Stack))
exp := &Label{Arity: 100}
s.Push(exp)
assert.Equal(t, exp, s.Pop())
// verify the length grows
for i := 0; i < initialStackHeight+1; i++ {
for i := 0; i < initialLabelStackHeight+1; i++ {
s.Push(&Label{})
}
assert.True(t, len(s.Stack) > initialStackHeight)
assert.True(t, len(s.Stack) > initialLabelStackHeight)
// verify the length is not shortened
for i := 0; i < len(s.Stack); i++ {
_ = s.Pop()
}
assert.True(t, len(s.Stack) > initialStackHeight)
assert.True(t, len(s.Stack) > initialLabelStackHeight)
}