Adds ExportedFunctions API on CompiledModule. (#681)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
23
api/wasm.go
23
api/wasm.go
@@ -173,7 +173,28 @@ type Closer interface {
|
||||
Close(context.Context) error
|
||||
}
|
||||
|
||||
// Function is a WebAssembly 1.0 (20191205) function exported from an instantiated module (wazero.Runtime InstantiateModule).
|
||||
// ExportedFunction is a WebAssembly function exported in a module (wazero.CompiledModule).
|
||||
//
|
||||
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#exports%E2%91%A0
|
||||
type ExportedFunction interface {
|
||||
// Name returns the name of this exported function which is unique across a module.
|
||||
// Note: the empty name is allowed in the WebAssembly specification so returned "" is meaningful.
|
||||
Name() string
|
||||
|
||||
// ParamTypes are the possibly empty sequence of value types accepted by a function with this signature.
|
||||
//
|
||||
// See ValueType documentation for encoding rules.
|
||||
ParamTypes() []ValueType
|
||||
|
||||
// ResultTypes are the possibly empty sequence of value types returned by a function with this signature.
|
||||
//
|
||||
// When WebAssembly 1.0 (20191205), there can be at most one result: https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#result-types%E2%91%A0
|
||||
//
|
||||
// See ValueType documentation for decoding rules.
|
||||
ResultTypes() []ValueType
|
||||
}
|
||||
|
||||
// Function is a WebAssembly function exported from an instantiated module (wazero.Runtime InstantiateModule).
|
||||
//
|
||||
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-func
|
||||
type Function interface {
|
||||
|
||||
@@ -268,6 +268,9 @@ type CompiledModule interface {
|
||||
//
|
||||
// Note: It is safe to call Close while having outstanding calls from an api.Module instantiated from this.
|
||||
Close(context.Context) error
|
||||
|
||||
// ExportedFunctions returns all the exported functions (api.ExportedFunction) in this module.
|
||||
ExportedFunctions() []api.ExportedFunction
|
||||
}
|
||||
|
||||
type compiledModule struct {
|
||||
@@ -288,6 +291,11 @@ func (c *compiledModule) Close(_ context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExportedFunctions implements CompiledModule.ExportedFunctions
|
||||
func (c *compiledModule) ExportedFunctions() []api.ExportedFunction {
|
||||
return c.module.ExportedFunctions()
|
||||
}
|
||||
|
||||
// CompileConfig allows you to override what was decoded from wasm, prior to compilation (ModuleBuilder.Compile or
|
||||
// Runtime.CompileModule).
|
||||
//
|
||||
|
||||
41
internal/wasm/module_exports.go
Normal file
41
internal/wasm/module_exports.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package wasm
|
||||
|
||||
import "github.com/tetratelabs/wazero/api"
|
||||
|
||||
// ExportedFunctions returns the implementations of api.ExportedFunction.
|
||||
func (m *Module) ExportedFunctions() (ret []api.ExportedFunction) {
|
||||
for _, exp := range m.ExportSection {
|
||||
if exp.Type == ExternTypeFunc {
|
||||
tp := m.TypeOfFunction(exp.Index)
|
||||
ret = append(ret, &exportedFunction{
|
||||
exportedName: exp.Name,
|
||||
params: tp.Params,
|
||||
results: tp.Results,
|
||||
})
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// exportedFunction implements api.ExportedFunction
|
||||
type exportedFunction struct {
|
||||
// exportedName is the name of export entry of this function,
|
||||
// which might differ from the one in the name custom section etc.
|
||||
exportedName string
|
||||
params, results []ValueType
|
||||
}
|
||||
|
||||
// Name implements api.ExportedFunction Name.
|
||||
func (e *exportedFunction) Name() string {
|
||||
return e.exportedName
|
||||
}
|
||||
|
||||
// ParamTypes implements api.ExportedFunction ParamTypes.
|
||||
func (e *exportedFunction) ParamTypes() []ValueType {
|
||||
return e.params
|
||||
}
|
||||
|
||||
// ResultTypes implements api.ExportedFunction ResultTypes.
|
||||
func (e *exportedFunction) ResultTypes() []ValueType {
|
||||
return e.results
|
||||
}
|
||||
113
internal/wasm/module_exports_test.go
Normal file
113
internal/wasm/module_exports_test.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package wasm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/internal/testing/require"
|
||||
)
|
||||
|
||||
func TestModule_ExportedFunctions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
m *Module
|
||||
exp []api.ExportedFunction
|
||||
}{
|
||||
{
|
||||
name: "no exports",
|
||||
m: &Module{},
|
||||
},
|
||||
{
|
||||
name: "no functions",
|
||||
m: &Module{
|
||||
ExportSection: []*Export{{Type: ExternTypeGlobal, Index: 0}},
|
||||
GlobalSection: []*Global{{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without imports",
|
||||
m: &Module{
|
||||
ExportSection: []*Export{
|
||||
{Name: "function_index=0", Type: ExternTypeFunc, Index: 0},
|
||||
{Name: "function_index=2", Type: ExternTypeFunc, Index: 2},
|
||||
{Name: "", Type: ExternTypeGlobal, Index: 0},
|
||||
{Name: "function_index=1", Type: ExternTypeFunc, Index: 1},
|
||||
},
|
||||
GlobalSection: []*Global{{}},
|
||||
FunctionSection: []Index{1, 2, 0},
|
||||
TypeSection: []*FunctionType{
|
||||
{Params: []ValueType{}, Results: []ValueType{}},
|
||||
{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
||||
{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
||||
},
|
||||
},
|
||||
exp: []api.ExportedFunction{
|
||||
&exportedFunction{
|
||||
exportedName: "function_index=0",
|
||||
params: []ValueType{ValueTypeF64, ValueTypeI32},
|
||||
results: []ValueType{ValueTypeV128, ValueTypeI64},
|
||||
},
|
||||
&exportedFunction{
|
||||
exportedName: "function_index=2", params: []ValueType{}, results: []ValueType{},
|
||||
},
|
||||
&exportedFunction{
|
||||
exportedName: "function_index=1",
|
||||
params: []ValueType{ValueTypeF64, ValueTypeF32},
|
||||
results: []ValueType{ValueTypeI64},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with imports",
|
||||
m: &Module{
|
||||
ImportSection: []*Import{{
|
||||
Type: ExternTypeFunc,
|
||||
DescFunc: 2, // Index of type.
|
||||
}},
|
||||
ExportSection: []*Export{
|
||||
{Name: "imported_function", Type: ExternTypeFunc, Index: 0},
|
||||
{Name: "function_index=1", Type: ExternTypeFunc, Index: 1},
|
||||
{Name: "function_index=2", Type: ExternTypeFunc, Index: 2},
|
||||
},
|
||||
FunctionSection: []Index{1, 0},
|
||||
TypeSection: []*FunctionType{
|
||||
{Params: []ValueType{}, Results: []ValueType{}},
|
||||
{Params: []ValueType{ValueTypeF64, ValueTypeI32}, Results: []ValueType{ValueTypeV128, ValueTypeI64}},
|
||||
{Params: []ValueType{ValueTypeF64, ValueTypeF32}, Results: []ValueType{ValueTypeI64}},
|
||||
},
|
||||
},
|
||||
exp: []api.ExportedFunction{
|
||||
&exportedFunction{
|
||||
exportedName: "imported_function",
|
||||
params: []ValueType{ValueTypeF64, ValueTypeF32},
|
||||
results: []ValueType{ValueTypeI64},
|
||||
},
|
||||
&exportedFunction{
|
||||
exportedName: "function_index=1",
|
||||
params: []ValueType{ValueTypeF64, ValueTypeI32},
|
||||
results: []ValueType{ValueTypeV128, ValueTypeI64},
|
||||
},
|
||||
&exportedFunction{
|
||||
exportedName: "function_index=2",
|
||||
params: []ValueType{},
|
||||
results: []ValueType{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
actual := tc.m.ExportedFunctions()
|
||||
require.Equal(t, tc.exp, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportedFunction(t *testing.T) {
|
||||
f := &exportedFunction{exportedName: "abc", params: []ValueType{ValueTypeI32}, results: []ValueType{ValueTypeV128}}
|
||||
require.Equal(t, "abc", f.exportedName)
|
||||
require.Equal(t, []ValueType{ValueTypeI32}, f.ParamTypes())
|
||||
require.Equal(t, []ValueType{ValueTypeV128}, f.ResultTypes())
|
||||
}
|
||||
Reference in New Issue
Block a user