...
1 package wasm
2
3 import (
4 "context"
5 "fmt"
6
7 "github.com/tetratelabs/wazero/api"
8 "github.com/tetratelabs/wazero/internal/internalapi"
9 )
10
11
12
13
14 func (m *ModuleInstance) LookupFunction(t *TableInstance, typeId FunctionTypeID, tableOffset Index) api.Function {
15 fm, index := m.Engine.LookupFunction(t, typeId, tableOffset)
16 if source := fm.Source; source.IsHostModule {
17
18
19
20 def := &source.FunctionDefinitionSection[index]
21 goF := source.CodeSection[index].GoFunc
22 switch typed := goF.(type) {
23 case api.GoFunction:
24
25 return &lookedUpGoFunction{def: def, g: goFunctionAsGoModuleFunction(typed)}
26 case api.GoModuleFunction:
27 return &lookedUpGoFunction{def: def, lookedUpModule: m, g: typed}
28 default:
29 panic(fmt.Sprintf("unexpected GoFunc type: %T", goF))
30 }
31 } else {
32 return fm.Engine.NewFunction(index)
33 }
34 }
35
36
37 type lookedUpGoFunction struct {
38 internalapi.WazeroOnly
39 def *FunctionDefinition
40
41 lookedUpModule *ModuleInstance
42 g api.GoModuleFunction
43 }
44
45
46 func goFunctionAsGoModuleFunction(g api.GoFunction) api.GoModuleFunction {
47 return api.GoModuleFunc(func(ctx context.Context, _ api.Module, stack []uint64) {
48 g.Call(ctx, stack)
49 })
50 }
51
52
53 func (l *lookedUpGoFunction) Definition() api.FunctionDefinition { return l.def }
54
55
56 func (l *lookedUpGoFunction) Call(ctx context.Context, params ...uint64) ([]uint64, error) {
57 typ := l.def.Functype
58 stackSize := typ.ParamNumInUint64
59 rn := typ.ResultNumInUint64
60 if rn > stackSize {
61 stackSize = rn
62 }
63 stack := make([]uint64, stackSize)
64 copy(stack, params)
65 return stack[:rn], l.CallWithStack(ctx, stack)
66 }
67
68
69 func (l *lookedUpGoFunction) CallWithStack(ctx context.Context, stack []uint64) error {
70
71 l.g.Call(ctx, l.lookedUpModule, stack)
72 return nil
73 }
74
View as plain text