package experimental

import "github.com/tetratelabs/wazero/experimental"

Package experimental includes features we aren't yet sure about. These are enabled with context.Context keys.

Note: All features here may be changed or deleted at any time, so use with caution!

Example (CustomListenerFactory)

This shows how to make a listener that counts go function calls.

Code:play 

package main

import (
	"context"
	_ "embed"
	"fmt"
	"log"
	"sort"

	"github.com/tetratelabs/wazero"
	"github.com/tetratelabs/wazero/api"
	"github.com/tetratelabs/wazero/experimental"
	"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
)

// listenerWasm was generated by the following:
//
//	cd testdata; wat2wasm --debug-names listener.wat
//
//go:embed logging/testdata/listener.wasm
var listenerWasm []byte

// uniqGoFuncs implements both FunctionListenerFactory and FunctionListener
type uniqGoFuncs map[string]struct{}

// callees returns the go functions called.
func (u uniqGoFuncs) callees() []string {
	ret := make([]string, 0, len(u))
	for k := range u {
		ret = append(ret, k)
	}
	// Sort names for consistent iteration
	sort.Strings(ret)
	return ret
}

// NewListener implements FunctionListenerFactory.NewListener
func (u uniqGoFuncs) NewListener(def api.FunctionDefinition) experimental.FunctionListener {
	if def.GoFunction() == nil {
		return nil // only track go funcs
	}
	return u
}

// Before implements FunctionListener.Before
func (u uniqGoFuncs) Before(ctx context.Context, _ api.Module, def api.FunctionDefinition, _ []uint64) context.Context {
	u[def.DebugName()] = struct{}{}
	return ctx
}

// After implements FunctionListener.After
func (u uniqGoFuncs) After(context.Context, api.Module, api.FunctionDefinition, error, []uint64) {}

// This shows how to make a listener that counts go function calls.
func main() {
	u := uniqGoFuncs{}

	// Set context to one that has an experimental listener
	ctx := context.WithValue(context.Background(), experimental.FunctionListenerFactoryKey{}, u)

	r := wazero.NewRuntime(ctx)
	defer r.Close(ctx) // This closes everything this Runtime created.

	wasi_snapshot_preview1.MustInstantiate(ctx, r)

	mod, err := r.Instantiate(ctx, listenerWasm)
	if err != nil {
		log.Panicln(err)
	}

	for i := 0; i < 5; i++ {
		if _, err = mod.ExportedFunction("rand").Call(ctx, 4); err != nil {
			log.Panicln(err)
		}
	}

	// A Go function was called multiple times, but we should only see it once.
	for _, f := range u.callees() {
		fmt.Println(f)
	}

}

Output:

wasi_snapshot_preview1.random_get

Index

Examples

Types

type FunctionListener

type FunctionListener interface {
	// Before is invoked before a function is called. The returned context will
	// be used as the context of this function call.
	//
	// # Params
	//
	//   - ctx: the context of the caller function which must be the same
	//	   instance or parent of the result.
	//   - mod: the calling module.
	//   - def: the function definition.
	//   - paramValues:  api.ValueType encoded parameters.
	//
	// Note: api.Memory is meant for inspection, not modification.
	Before(ctx context.Context, mod api.Module, def api.FunctionDefinition, paramValues []uint64) context.Context

	// After is invoked after a function is called.
	//
	// # Params
	//
	//   - ctx: the context returned by Before.
	//   - mod: the calling module.
	//   - def: the function definition.
	//   - err: nil if the function didn't err
	//   - resultValues: api.ValueType encoded results.
	//
	// Note: api.Memory is meant for inspection, not modification.
	After(ctx context.Context, mod api.Module, def api.FunctionDefinition, err error, resultValues []uint64)
}

FunctionListener can be registered for any function via FunctionListenerFactory to be notified when the function is called.

type FunctionListenerFactory

type FunctionListenerFactory interface {
	// NewListener returns a FunctionListener for a defined function. If nil is
	// returned, no listener will be notified.
	NewListener(api.FunctionDefinition) FunctionListener
}

FunctionListenerFactory returns FunctionListeners to be notified when a function is called.

type FunctionListenerFactoryKey

type FunctionListenerFactoryKey struct{}

FunctionListenerFactoryKey is a context.Context Value key. Its associated value should be a FunctionListenerFactory.

See https://github.com/tetratelabs/wazero/issues/451

Source Files

experimental.go listener.go

Directories

PathSynopsis
experimental/gojsPackage gojs allows you to run wasm binaries compiled by Go when `GOARCH=wasm GOOS=js`.
experimental/gojs/example
experimental/logging
Version
v1.0.1
Published
Mar 29, 2023
Platform
js/wasm
Imports
2 packages
Last checked
1 minute ago

Tools for package owners.