97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
package wasm
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
"testing"
|
|
|
|
"github.com/tetratelabs/wazero/api"
|
|
"github.com/tetratelabs/wazero/internal/testing/require"
|
|
)
|
|
|
|
func TestModuleInstance_LookupFunction(t *testing.T) {
|
|
var called int
|
|
hostModule := &Module{
|
|
IsHostModule: true,
|
|
CodeSection: []Code{
|
|
{GoFunc: api.GoFunc(func(context.Context, []uint64) {
|
|
called++
|
|
})},
|
|
{GoFunc: api.GoModuleFunc(func(context.Context, api.Module, []uint64) {
|
|
called++
|
|
})},
|
|
},
|
|
FunctionDefinitionSection: []FunctionDefinition{{}, {}},
|
|
}
|
|
|
|
me := &mockModuleEngine{
|
|
lookupEntries: map[Index]mockModuleEngineLookupEntry{
|
|
0: {m: &ModuleInstance{Source: hostModule}, index: 0},
|
|
1: {m: &ModuleInstance{Source: hostModule}, index: 1},
|
|
},
|
|
}
|
|
m := &ModuleInstance{Engine: me}
|
|
|
|
t.Run("host", func(t *testing.T) {
|
|
gf, ok := m.LookupFunction(nil, 0, 0).(*lookedUpGoFunction)
|
|
require.True(t, ok)
|
|
require.Nil(t, gf.lookedUpModule) // GoFunction doesn't need looked up module.
|
|
require.Equal(t, &hostModule.FunctionDefinitionSection[0], gf.def)
|
|
err := gf.CallWithStack(context.Background(), nil)
|
|
require.NoError(t, err)
|
|
|
|
gmf, ok := m.LookupFunction(nil, 0, 1).(*lookedUpGoFunction)
|
|
require.True(t, ok)
|
|
require.Equal(t, m, gmf.lookedUpModule)
|
|
require.Equal(t, hostModule.CodeSection[1].GoFunc, gmf.g)
|
|
require.Equal(t, &hostModule.FunctionDefinitionSection[1], gmf.def)
|
|
err = gmf.CallWithStack(context.Background(), nil)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 2, called)
|
|
})
|
|
|
|
t.Run("wasm", func(t *testing.T) {
|
|
me.lookupEntries[2] = mockModuleEngineLookupEntry{
|
|
m: &ModuleInstance{
|
|
Source: &Module{},
|
|
Engine: me,
|
|
},
|
|
index: 100,
|
|
}
|
|
wf, ok := m.LookupFunction(nil, 0, 2).(*mockCallEngine)
|
|
require.True(t, ok)
|
|
require.Equal(t, Index(100), wf.index)
|
|
})
|
|
}
|
|
|
|
func Test_lookedUpGoModuleFunction(t *testing.T) {
|
|
def := &FunctionDefinition{
|
|
Functype: &FunctionType{
|
|
ParamNumInUint64: 2, ResultNumInUint64: 1,
|
|
Params: []ValueType{ValueTypeI64, ValueTypeF64}, Results: []ValueType{ValueTypeI64},
|
|
},
|
|
}
|
|
|
|
expMod := &ModuleInstance{}
|
|
var called bool
|
|
l := &lookedUpGoFunction{
|
|
lookedUpModule: expMod,
|
|
def: def,
|
|
g: api.GoModuleFunc(
|
|
func(ctx context.Context, mod api.Module, stack []uint64) {
|
|
require.Equal(t, expMod, mod)
|
|
require.Equal(t, []uint64{math.MaxUint64, math.Float64bits(math.Pi)}, stack)
|
|
stack[0] = 1
|
|
called = true
|
|
},
|
|
),
|
|
}
|
|
require.Equal(t, l.Definition().(*FunctionDefinition), l.def)
|
|
result, err := l.Call(context.Background(), math.MaxUint64, math.Float64bits(math.Pi))
|
|
require.NoError(t, err)
|
|
require.True(t, called)
|
|
require.Equal(t, []uint64{1}, result)
|
|
require.Equal(t, 1, len(result))
|
|
}
|