Skip to content

Add host imports ​

A host import is a Go function called by Wasm. The plugin's host.import.define grant names the exact import modules it may add.

Get the registrar ​

go
imports, err := reg.HostImports()
if err != nil {
	return err
}

Return err before registering functions. A grant for acme_math does not cover a parent, child, or wildcard name; flat registration preserves the exact module and function identity.

Write the callback ​

go
func addOne(value int32) int32 {
	return value + 1
}

Ordinary supported Go signatures are inferred without runtime reflection. The adapter supports a fixed set of signatures; it does not accept every Go function with Wasm-compatible types. Use func(wago.HostCall) for arbitrary supported scalar/reference arity, or func(wago.Caller, wago.HostCall) when the callback needs guest state.

For example, use the portable callback for a no-argument function returning i32:

go
imports.HostFunc("acme_math", "answer", func(call wago.HostCall) {
	call.SetI32(0, 42)
}).Results(wago.ValI32)

A plain func() int32 is not a supported inferred signature. Registration reports unsupported host callback for it.

Declare its Wasm signature ​

go
imports.HostFunc("acme_math", "add_one", addOne).
	Params(wago.ValI32).
	Results(wago.ValI32)

Wago checks that signature against the importing module.

Guest memory ​

Caller.Memory() returns memory 0 for the duration of a caller-aware callback. Check the range before slicing and do not retain the slice, Caller, or HostCall.

go
memory := caller.Memory()
offset := uint64(uint32(call.I32(0)))
if offset >= uint64(len(memory)) {
	return
}

Use GuestStorageHostModule for indexed memory, Memory64 metadata, exact GC types, or Wasm GC arrays. examples/21-guest-storage shows the checked borrow.

Guest capabilities ​

Register a capability when the import gives Wasm a permission the host may deny:

go
err := reg.GuestCapability(
	wago.Capability("clock.read"),
	wago.CapabilityDocs("read the host clock"),
)

Handle that error, then attach the capability to the function builder. Declaring a capability alone does not require it for an import:

go
if err != nil {
    return err
}
imports.HostFunc("acme_clock", "now_millis", func(call wago.HostCall) {
    call.SetI64(0, time.Now().UnixMilli())
}).Results(wago.ValI64).Capability(wago.Capability("clock.read"))

This callback imports time; the definition and reviewed grant must include acme_clock in the host.import.define module scope. The guest capability governs Wasm. The Plugin Authority governs trusted Go plugin code.

Run examples/08-custom-plugin for a complete import and capability.

Run the published examples without a source checkout:

sh
go run github.com/wago-org/wago/examples/08-custom-plugin@b084a7c9343f81a9120ca80a13d133884e88d514
go run github.com/wago-org/wago/examples/21-guest-storage@b084a7c9343f81a9120ca80a13d133884e88d514

Released under the Apache 2.0 License.