wasmexec

package module
v0.0.0-...-6554945 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2022 License: MIT Imports: 9 Imported by: 0

README

wasmexec Go Report Card GoDoc

wasmexec is runtime-agnostic implementation of Go's wasm_exec.js in Go. It currently has import hooks for wasmer, wasmtime and wazero. Each runtime-dedicated package has its own example of an implementation that can run any of the examples.

1. Minimum implementation

When a Go Wasm module is instantiated, it needs to be wrapped up in a structure that implements the minimum set of methods in order to run. wasmexec.New() requires at least this Instance interface.

type Instance interface {
    Memory

    GetSP() (uint32, error)
    Resume() error
}

The GetSP() and Resume() methods are calls directly to the Go Wasm exports. The Memory interface wraps the Go Wasm module's memory.

type Memory interface {
    Range(offset, length uint32) ([]byte, error)
		
    GetUInt32(offset uint32) (uint32, error)
    GetInt64(offset uint32) (int64, error)
    GetFloat64(offset uint32) (float64, error)
    SetUInt8(offset uint32, val uint8) error
    SetUInt32(offset, val uint32) error
    SetInt64(offset uint32, val int64) error
    SetFloat64(offset uint32, val float64) error
}

If your runtime exposes the memory as a []byte (as wasmer and wasmtime do) then you can easily use the NewMemory() function to satisfy this interface. If not, a custom implementation needs to be written (like wazero).

2. Optional implementation

The above-mentioned instance wrapper may also implement additional methods for extra functionality.

2.1. Debug logging

If the debugLogger interface is implemented, Debug() is called with debug messages. This is only useful when you're debugging issues with this package.

type debugLogger interface {
    Debug(format string, params ...any)
}
2.2. Error logging

If the errorLogger interface is implemented, Error() is called for any error that might pop up during execution. At this stage, it is probably useful to implement this as this package isn't battle tested yet.

type errorLogger interface {
    Error(format string, params ...any)
}
2.3. Writer

If the fdWriter interface is implemented, Write() is called for any data being sent to stdout or stderr. It is highly recommended that this is implemented.

type fdWriter interface {
    Write(fd int, data []byte) (n int, err error)
}

2.4. Exiting

If the exiter interface is implemented, Exit() is called whenever the call to the run() Wasm function is done.

type exiter interface {
    Exit(code int)
}
2.5. waPC

If the hostCaller interface is implemented, HostCall() is called whenever the waPC guest sends information to the host. More information on this can be found in the wapc package.

type hostCaller interface {
    HostCall(string, string, string, []byte) ([]byte, error)
}

3. js.FuncOf()

The guest can use js.FuncOf() to create functions that can be called from the host.

var uint8Array = js.Global().Get("Uint8Array")

func main() {
    myEvent := js.FuncOf(func(this js.Value, args []js.Value) any {
        arg := args[0]

        if arg.InstanceOf(uint8Array) {
            dst := make([]byte, arg.Length())
            js.CopyBytesToGo(dst, arg)
						
            fmt.Printf("Received: %v\n", string(dst))
        }
				
        return nil
    }
		
    js.Global().Set("myEvent", myEvent)
}

On the host these functions can be called using Call() on *wasmexec.Module:

mod.Call("myEvent", []byte("Hello World!"))

4. Acknowledgements

This implementation was made possible by allowing me to peek at mattn's implementation as well as Vedhavyas Singareddi's go-wasm-adapter.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrFault = errors.New("bad address")

ErrFault is returned whenever memory was accessed that was not addressable.

View Source
var NaN = math.NaN()

NaN describes a not-a-number value.

Functions

func SetArgs

func SetArgs(mem Memory, args, envs []string) (int32, int32, error)

SetArgs sets the specified arguments and environment variables.

Types

type Instance

type Instance interface {
	Memory

	// Get the SP value.
	GetSP() (uint32, error)

	// Resume the execution of Go code until it needs to wait for an event.
	Resume() error
}

Instance describes an instance of a Wasm module.

type Memory

type Memory interface {
	Range(offset, length uint32) ([]byte, error)

	GetUInt32(offset uint32) (uint32, error)
	GetInt64(offset uint32) (int64, error)
	GetFloat64(offset uint32) (float64, error)
	SetUInt8(offset uint32, val uint8) error
	SetUInt32(offset, val uint32) error
	SetInt64(offset uint32, val int64) error
	SetFloat64(offset uint32, val float64) error
}

Memory describes an instantiated module's memory.

func NewMemory

func NewMemory(mem []byte) Memory

NewMemory returns a new Memory.

type Module

type Module struct {
	// contains filtered or unexported fields
}

Module implements the JavaScript imports that a Go program compiled with GOOS=js expects.

func New

func New(instance Instance) *Module

New returns a new Module.

func (*Module) Call

func (mod *Module) Call(name string, args ...any) (any, error)

Call a function created by js.FuncOf().

func (*Module) ClearTimeoutEvent

func (mod *Module) ClearTimeoutEvent(sp uint32)

ClearTimeoutEvent clears a timeout event scheduled by ScheduleTimeoutEvent.

This method is called from the runtime package.

func (*Module) CopyBytesToGo

func (mod *Module) CopyBytesToGo(sp uint32)

CopyBytesToGo copies bytes from JavaScript to Go.

func (*Module) CopyBytesToJS

func (mod *Module) CopyBytesToJS(sp uint32)

CopyBytesToJS copies bytes from Go to JavaScript.

func (*Module) Debug

func (mod *Module) Debug(sp uint32)

Debug prints some debugging information ... I guess?

func (*Module) FinalizeRef

func (mod *Module) FinalizeRef(sp uint32)

FinalizeRef removes a value from memory.

This method is called from various places in syscall/js.Value.

func (*Module) GetRandomData

func (mod *Module) GetRandomData(sp uint32)

GetRandomData returns random data.

This method is called from the runtime package.

func (*Module) Invoke

func (mod *Module) Invoke(operation string, payload []byte) ([]byte, error)

Invoke calls operation with the specified payload and returns a []byte payload.

func (*Module) Nanotime1

func (mod *Module) Nanotime1(sp uint32)

Nanotime1 returns the current time in nanoseconds.

This method is called from the runtime package.

func (*Module) ResetMemoryDataView

func (mod *Module) ResetMemoryDataView(sp uint32)

ResetMemoryDataView is called whenever WebAssembly's memory.grow instruction has been used.

This method is called from the runtime package.

func (*Module) ScheduleTimeoutEvent

func (mod *Module) ScheduleTimeoutEvent(sp uint32)

ScheduleTimeoutEvent is called whenever an event needs to be scheduled after a certain amount of milliseconds.

This method is called from the runtime package.

func (*Module) StringVal

func (mod *Module) StringVal(sp uint32)

StringVal stores a value as a string.

This method is called from syscall/js.ValueOf().

func (*Module) ValueCall

func (mod *Module) ValueCall(sp uint32)

ValueCall calls the method on an object with the give arguments.

This method is called from syscall/js.Value.Call().

func (*Module) ValueDelete

func (mod *Module) ValueDelete(sp uint32)

ValueDelete deletes a property on an object.

This method is called from syscall/js.Value.Delete().

func (*Module) ValueGet

func (mod *Module) ValueGet(sp uint32)

ValueGet returns the JavaScript property of an object.

This method is called from syscall/js.Value.Get().

func (*Module) ValueIndex

func (mod *Module) ValueIndex(sp uint32)

ValueIndex returns a value at a particular index in an array.

This method is called from syscall/js.Value.Index().

func (*Module) ValueInstanceOf

func (mod *Module) ValueInstanceOf(sp uint32)

ValueInstanceOf returns true when v is an instance of type t.

This method is called from syscall/js.Value.InstanceOf().

func (*Module) ValueInvoke

func (mod *Module) ValueInvoke(sp uint32)

ValueInvoke calls the value v with the specified arguments.

This method is called from syscall/js.Value.Invoke().

func (*Module) ValueLength

func (mod *Module) ValueLength(sp uint32)

ValueLength returns the JavaScript property of "length" of v.

This method is called from syscall/js.Value.Length().

func (*Module) ValueLoadString

func (mod *Module) ValueLoadString(sp uint32)

ValueLoadString loads a string into memory.

This method is called from syscall/js.Value.jsString().

func (*Module) ValueNew

func (mod *Module) ValueNew(sp uint32)

ValueNew calls a constructor function with the given arguments. This is akin to JavaScript's "new" operator.

This method is called from syscall/js.Value.New().

func (*Module) ValuePrepareString

func (mod *Module) ValuePrepareString(sp uint32)

ValuePrepareString converts a value to a string and stores it.

This method is called from syscall/js.Value.jsString() for jsString, Boolean and Number types.

func (*Module) ValueSet

func (mod *Module) ValueSet(sp uint32)

ValueSet sets a value on a property on an object.

This method is called from syscall/js.Value.Set().

func (*Module) ValueSetIndex

func (mod *Module) ValueSetIndex(sp uint32)

ValueSetIndex sets the value at a particular index of an array.

This method is called from syscall/js.Value.SetIndex().

func (*Module) Walltime

func (mod *Module) Walltime(sp uint32)

Walltime returns the current seconds and nanoseconds.

This method is called from the runtime package.

func (*Module) WasmExit

func (mod *Module) WasmExit(sp uint32)

WasmExit is called whenever the WASM program exits.

This method is called from the runtime package.

func (*Module) WasmWrite

func (mod *Module) WasmWrite(sp uint32)

WasmWrite writes data to a file descriptor.

This method is called from the runtime package.

Directories

Path Synopsis
examples
env

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL