diff --git a/go.mod b/go.mod index 39407c61b9..0001bdc7fa 100644 --- a/go.mod +++ b/go.mod @@ -63,7 +63,7 @@ require ( github.com/spf13/viper v1.13.0 github.com/stretchr/testify v1.8.0 github.com/testcontainers/testcontainers-go v0.13.0 - github.com/tetratelabs/wazero v1.0.0-pre.2 + github.com/tetratelabs/wazero v1.0.0-pre.3 github.com/twitchtv/twirp v8.1.2+incompatible github.com/xlab/treeprint v1.1.0 go.etcd.io/bbolt v1.3.6 diff --git a/go.sum b/go.sum index bbab1cf7fd..d565991736 100644 --- a/go.sum +++ b/go.sum @@ -1521,8 +1521,8 @@ github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BG github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/testcontainers/testcontainers-go v0.13.0 h1:OUujSlEGsXVo/ykPVZk3KanBNGN0TYb/7oKIPVn15JA= github.com/testcontainers/testcontainers-go v0.13.0/go.mod h1:z1abufU633Eb/FmSBTzV6ntZAC1eZBYPtaFsn4nPuDk= -github.com/tetratelabs/wazero v1.0.0-pre.2 h1:sHYi8DKUL7s7c4sKz6lw0pNqky5EogYK0Iq4pSIsDog= -github.com/tetratelabs/wazero v1.0.0-pre.2/go.mod h1:M8UDNECGm/HVjOfq0EOe4QfCY9Les1eq54IChMLETbc= +github.com/tetratelabs/wazero v1.0.0-pre.3 h1:Z5fbogMUGcERzaQb9mQU8+yJSy0bVvv2ce3dfR4wcZg= +github.com/tetratelabs/wazero v1.0.0-pre.3/go.mod h1:M8UDNECGm/HVjOfq0EOe4QfCY9Les1eq54IChMLETbc= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= diff --git a/pkg/module/module.go b/pkg/module/module.go index 2c6e7cb21f..d619cb6819 100644 --- a/pkg/module/module.go +++ b/pkg/module/module.go @@ -30,7 +30,7 @@ import ( ) var ( - exportFunctions = map[string]interface{}{ + logFunctions = map[string]api.GoModuleFunc{ "debug": logDebug, "info": logInfo, "warn": logWarn, @@ -40,32 +40,52 @@ var ( RelativeDir = filepath.Join(".trivy", "modules") ) -func logDebug(ctx context.Context, m api.Module, offset, size uint32) { - buf := readMemory(ctx, m, offset, size) +// logDebug is defined as an api.GoModuleFunc for lower overhead vs reflection. +func logDebug(ctx context.Context, mod api.Module, params []uint64) (_ []uint64) { + offset, size := uint32(params[0]), uint32(params[1]) + + buf := readMemory(ctx, mod, offset, size) if buf != nil { log.Logger.Debug(string(buf)) } + + return } -func logInfo(ctx context.Context, m api.Module, offset, size uint32) { - buf := readMemory(ctx, m, offset, size) +// logInfo is defined as an api.GoModuleFunc for lower overhead vs reflection. +func logInfo(ctx context.Context, mod api.Module, params []uint64) (_ []uint64) { + offset, size := uint32(params[0]), uint32(params[1]) + + buf := readMemory(ctx, mod, offset, size) if buf != nil { log.Logger.Info(string(buf)) } + + return } -func logWarn(ctx context.Context, m api.Module, offset, size uint32) { - buf := readMemory(ctx, m, offset, size) +// logWarn is defined as an api.GoModuleFunc for lower overhead vs reflection. +func logWarn(ctx context.Context, mod api.Module, params []uint64) (_ []uint64) { + offset, size := uint32(params[0]), uint32(params[1]) + + buf := readMemory(ctx, mod, offset, size) if buf != nil { log.Logger.Warn(string(buf)) } + + return } -func logError(ctx context.Context, m api.Module, offset, size uint32) { - buf := readMemory(ctx, m, offset, size) +// logError is defined as an api.GoModuleFunc for lower overhead vs reflection. +func logError(ctx context.Context, mod api.Module, params []uint64) (_ []uint64) { + offset, size := uint32(params[0]), uint32(params[1]) + + buf := readMemory(ctx, mod, offset, size) if buf != nil { log.Logger.Error(string(buf)) } + + return } func readMemory(ctx context.Context, m api.Module, offset, size uint32) []byte { @@ -242,14 +262,21 @@ func newWASMPlugin(ctx context.Context, r wazero.Runtime, code []byte) (*wasmMod ns := r.NewNamespace(ctx) // Instantiate a Go-defined module named "env" that exports functions. - _, err := r.NewHostModuleBuilder("env"). - ExportFunctions(exportFunctions). - Instantiate(ctx, ns) - if err != nil { + envBuilder := r.NewHostModuleBuilder("env") + + // Avoid reflection for logging as it implies an overhead of >1us per call. + for n, f := range logFunctions { + envBuilder.NewFunctionBuilder(). + WithGoModuleFunction(f, []api.ValueType{api.ValueTypeI32, api.ValueTypeI32}, []api.ValueType{}). + WithParameterNames("offset", "size"). + Export(n) + } + + if _, err := envBuilder.Instantiate(ctx, ns); err != nil { return nil, xerrors.Errorf("wasm module build error: %w", err) } - if _, err = wasi.NewBuilder(r).Instantiate(ctx, ns); err != nil { + if _, err := wasi.NewBuilder(r).Instantiate(ctx, ns); err != nil { return nil, xerrors.Errorf("WASI init error: %w", err) }