Documentation
¶
Overview ¶
Package runtime provides core functionality for loading, verifying, and executing WebAssembly modules.
The runtime package is the main interface for working with WASM plugins in Hookr. It handles loading modules from files, verifying their integrity, and facilitating communication between the runtime application and the plugins.
Creating a new Runtime ¶
A Runtime is the central component that manages a WASM plugin:
ctx := context.Background()
rt, err := runtime.New(ctx, runtime.WithFile("./plugin.wasm"))
if err != nil {
log.Fatalf("Failed to create engine: %v", err)
}
defer rt.Close(ctx)
Runtime Configuration ¶
The Runtime can be configured with various options:
rt, err := runtime.New(ctx,
// Load plugin from file
runtime.WithFile("./plugin.wasm"),
// Configure I/O
runtime.WithStdout(os.Stdout),
runtime.WithStderr(os.Stderr),
// Set a custom logger
runtime.WithLogger(func(msg string) {
log.Printf("[PLUGIN] %s", msg)
}),
// Register host functions
runtime.WithHostFns(myHostFn),
// Set a custom random source for deterministic behavior
runtime.WithRandSource(myRandSource),
)
Invoking Plugin Functions ¶
Plugin functions can be invoked directly with byte slices:
result, err := rt.Invoke(ctx, "function_name", []byte("input data"))
if err != nil {
log.Fatalf("Function call failed: %v", err)
}
fmt.Printf("Result: %s\n", result)
Type-Safe Function Calls ¶
For type safety, you can create strongly-typed function wrappers:
// Define request/response types that implement msgp.Marshaler/Unmarshaler
type Request struct {
Input string `msg:"input"`
}
type Response struct {
Output string `msg:"output"`
}
// Create a type-safe function
fn, err := runtime.PluginFn[*Request, *Response](engine, "process")
if err != nil {
log.Fatalf("Failed to create function wrapper: %v", err)
}
// Call the function
resp, err := fn.Call(&Request{Input: "test data"})
if err != nil {
log.Fatalf("Function call failed: %v", err)
}
fmt.Printf("Output: %s\n", resp.Output)
Registering Host Functions ¶
Host functions allow the plugin to call back into the host application:
// Define a runtime function
helloFn := func(input *HelloRequest) (*HelloResponse, error) {
return &HelloResponse{
Message: fmt.Sprintf("Hello, %s!", input.Name),
}, nil
}
// Register the runtime function
hostFn := runtime.HostFn("hello", helloFn)
engine, err := runtime.New(ctx,
runtime.WithFile("./plugin.wasm"),
runtime.WithHostFns(hostFn),
)
File Integrity ¶
To ensure the integrity of WASM files, you can use hashing:
engine, err := runtime.New(ctx,
runtime.WithFile("./plugin.wasm",
runtime.WithHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
runtime.WithHasher(runtime.Sha256Hasher{}),
),
)
Memory Management ¶
You can query memory usage of the WASM module:
memSize := rt.MemorySize()
fmt.Printf("WASM module memory size: %d bytes\n", memSize)
Index ¶
- func DefaultRuntime(ctx context.Context) (wazero.Runtime, error)
- type CallFn
- type CallFnT
- type CallFns
- type DefaultHasher
- type File
- type FileOption
- type Hasher
- type HostFunc
- type HostFuncByte
- type HostFunction
- type Marshaler
- type NewRuntime
- type Option
- func WithCallHandler(callHandler module.CallHandler) Option
- func WithFile(file string, opts ...FileOption) Option
- func WithHostFns(fns ...HostFunc) Option
- func WithLogger(logger logger.Logger) Option
- func WithRandSource(rand io.Reader) Option
- func WithStderr(stderr io.Writer) Option
- func WithStdout(stdout io.Writer) Option
- type PluginFunc
- type PluginFuncByte
- type PluginFuncSerial
- type Runtime
- func (e *Runtime) Close(ctx context.Context) error
- func (e *Runtime) Compile() error
- func (e *Runtime) Init() error
- func (e *Runtime) InitConfig()
- func (e *Runtime) InitHookr() error
- func (e *Runtime) InitRuntime() error
- func (e *Runtime) Instantiate() error
- func (e *Runtime) Invoke(ctx context.Context, operation string, payload []byte) ([]byte, error)
- func (e *Runtime) MemorySize() uint32
- func (e *Runtime) RegisterFunction(name string, fn CallFn)
- type Sha256Hasher
- type Unmarshaler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type CallFn ¶
CallFn is a function to be called by the CallHandler. It takes a context, a payload, and a serializer. It returns a byte slice and an error.
func Fn ¶
func Fn[In Unmarshaler, Out Marshaler](fn CallFnT[In, Out]) CallFn
Fn converts a strongly-typed GoFn to a byte-based CallFn allowing WASM plugins to call it. This allows for defining a strongly typed function, which can be called from WASM that will use a byte slice for input and output for communication.
type CallFnT ¶
type CallFnT[In Unmarshaler, Out Marshaler] func(ctx context.Context, input In) (Out, error)
CallFnT is a generic function that accepts and returns specific types It handles marshaling/unmarshaling automatically
type DefaultHasher ¶
type DefaultHasher struct{}
DefaultHasher is a default implementation of the Hasher interface. It does not actually hash anything, but is a placeholder for future implementations. It is used when no specific hashing algorithm is provided and no verification is needed.
The Hash method always returns an empty string, and IsValid only returns true when the hash is empty.
Example:
hasher := DefaultHasher{}
// Always returns empty string
hash, _ := hasher.Hash([]byte("data"))
// Returns true only when hash is empty
isValid := hasher.IsValid("", []byte("data")) // true
isValid = hasher.IsValid("some-hash", []byte("data")) // false
type File ¶
File is a struct that represents a WebAssembly module that is stored in a file. We can possibly add more types of Wasm modules in the future, which have different sources.
func NewFile ¶
func NewFile(path string, opts ...FileOption) (*File, error)
NewFile creates a new File instance and verifies it. If the file or name is invalid, an error is returned. Otherwise the *File is returned.
type FileOption ¶
type FileOption func(*File)
func WithHash ¶
func WithHash(hash string) FileOption
WithHash sets the expected Hash field of a File
func WithHasher ¶
func WithHasher(hasher Hasher) FileOption
WithHasher sets the Hasher to use for validating the hash of the File
type Hasher ¶
type Hasher interface {
// Hash returns a hash for the provided data
Hash(data []byte) (string, error)
// IsValid checks if a hash and data match
IsValid(hash string, data []byte) bool
}
Hasher hashes and validates byte arrays. It provides functionality for computing cryptographic hashes of data and validating data against a previously computed hash.
There are two built-in implementations:
- Sha256Hasher: Uses the SHA-256 algorithm for secure hashing
- DefaultHasher: A no-op implementation that performs no actual hashing
Example:
// Using Sha256Hasher
hasher := Sha256Hasher{}
// Compute hash of a file
data, _ := os.ReadFile("plugin.wasm")
hash, _ := hasher.Hash(data)
fmt.Println("SHA-256 hash:", hash)
// Verify file integrity
isValid := hasher.IsValid(hash, data)
fmt.Println("Is valid:", isValid)
type HostFuncByte ¶
type HostFuncByte struct {
// contains filtered or unexported fields
}
HostFuncByte is a wrapper for CallFn that provides a name and a function
func HostFnByte ¶
func HostFnByte(name string, fn CallFn) *HostFuncByte
HostFnByte is a function that takes a byte slice and returns a byte slice It is used to call a function that takes a byte slice and returns a byte slice
func (HostFuncByte) Fn ¶
func (f HostFuncByte) Fn() (name string, fn CallFn)
Fn returns the name and function to be called This is used to register the function with the host
type HostFunction ¶
type HostFunction[In Unmarshaler, Out Marshaler] struct { // contains filtered or unexported fields }
HostFunction is a wrapper for CallFnT that provides a name and a function This is used to register the function with the host
func HostFnSerial ¶
func HostFnSerial[In Unmarshaler, Out Marshaler]( name string, fn CallFnT[In, Out], ) *HostFunction[In, Out]
func (*HostFunction[In, Out]) Fn ¶
func (f *HostFunction[In, Out]) Fn() (name string, fn CallFn)
type NewRuntime ¶
NewRuntime returns a new wazero runtime which is called when the New method on hookr.Runtime is called. The result is closed upon wapc.Module Close.
type Option ¶
func WithCallHandler ¶
func WithCallHandler(callHandler module.CallHandler) Option
WithCallHandler sets the call handler for the engine.
func WithFile ¶
func WithFile(file string, opts ...FileOption) Option
WithFile sets the file for the engine.
func WithHostFns ¶
WithHostFns sets the host functions which are callable from the plugin.
func WithLogger ¶
WithLogger sets the logger for the engine.
func WithRandSource ¶
WithRandSource sets the random source for the runtime.
func WithStderr ¶
WithStderr sets the stderr writer for the engine.
func WithStdout ¶
WithStdout sets the stdout writer for the engine.
type PluginFunc ¶
type PluginFuncByte ¶
type PluginFuncByte struct {
Name string
// contains filtered or unexported fields
}
PluginFuncByte is a function that takes a byte slice and returns a byte slice
func PluginFnByte ¶
func PluginFnByte( rt *Runtime, name string, ) (*PluginFuncByte, error)
PluginFnByte creates a new PluginFunc with the given name and engine. This will always be a byte slice in and out.
type PluginFuncSerial ¶
type PluginFuncSerial[In Marshaler, Out Unmarshaler] struct { Name string // contains filtered or unexported fields }
func PluginFnSerial ¶
func PluginFnSerial[In Marshaler, Out Unmarshaler]( rt *Runtime, name string, ) (*PluginFuncSerial[In, Out], error)
Will create a new PluginFunc with the given name and engine. This is used to register the function with the host
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
func (*Runtime) Compile ¶
Compile compiles the plugin module. It must be called after the runtime is initialized and before the module is instantiated.
func (*Runtime) Init ¶
Init initializes the engine by setting up the runtime, config, and hookr. It is called when the engine is created.
func (*Runtime) InitConfig ¶
func (e *Runtime) InitConfig()
InitConfig initializes the wazero module config with the default settings.
func (*Runtime) InitHookr ¶
InitHookr initializes the hookr host module and sets it to the wazero runtime.
func (*Runtime) InitRuntime ¶
Will initialize the wazero runtime
func (*Runtime) Instantiate ¶
Instantiate instantiates the compiled module. It must be called after the module is compiled. It will also call the WASI and hookr start functions if
func (*Runtime) MemorySize ¶
MemorySize returns the size of the memory for this instance. This is the size in bytes, not the number of pages.
func (*Runtime) RegisterFunction ¶
RegisterFunction registers a host function with the engine.
type Sha256Hasher ¶
type Sha256Hasher struct{}
Sha256Hasher is an implementation of the Hasher interface. It uses SHA-256 hashing algorithm to hash and validate data. This provides a secure way to verify the integrity of WebAssembly modules.
Example:
hasher := Sha256Hasher{}
hash, _ := hasher.Hash(wasmBytes)
fmt.Println("Use this hash for verification:", hash)