wasmtime

package module
v0.16.2 Latest Latest
Warning

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

Go to latest
Published: May 15, 2020 License: Apache-2.0 Imports: 8 Imported by: 29

README

wasmtime-go

Go embedding of Wasmtime

A Bytecode Alliance project

CI status Documentation Code Coverage

Installation

go get -u github.com/bytecodealliance/wasmtime-go@v0.16.1

Be sure to check out the API documentation!

This Go library uses CGO to consume the C API of the Wasmtime project which is written in Rust. Precompiled binaries of Wasmtime are checked into this repository on tagged releases so you won't have to install Wasmtime locally, but it means that this project only works on Linux x86_64, macOS x86_64 , and Windows x86_64 currently. Buliding on other platforms will need to arrange to build Wasmtime and use CGO_* env vars to compile correctly.

Please note that currently this project requires Go 1.13.10 when run on macOS. There seems to be a regression in Go 1.14 (see issue #10) that can cause a segfault.

Usage

A "Hello, world!" example of using this package looks like:

package main

import (
    "fmt"
    "github.com/bytecodealliance/wasmtime-go"
)

func main() {
    // Almost all operations in wasmtime require a contextual `store`
    // argument to share, so create that first
    store := wasmtime.NewStore(wasmtime.NewEngine())

    // Compiling modules requires WebAssembly binary input, but the wasmtime
    // package also supports converting the WebAssembly text format to the
    // binary format.
    wasm, err := wasmtime.Wat2Wasm(`
      (module
        (import "" "hello" (func $hello))
        (func (export "run")
          (call $hello))
      )
    `)
    check(err)

    // Once we have our binary `wasm` we can compile that into a `*Module`
    // which represents compiled JIT code.
    module, err := wasmtime.NewModule(store, wasm)
    check(err)

    // Our `hello.wat` file imports one item, so we create that function
    // here.
    item := wasmtime.WrapFunc(store, func() {
        fmt.Println("Hello from Go!")
    })

    // Next up we instantiate a module which is where we link in all our
    // imports. We've got one import so we pass that in here.
    instance, err := wasmtime.NewInstance(module, []*wasmtime.Extern{item.AsExtern()})
    check(err)

    // After we've instantiated we can lookup our `run` function and call
    // it.
    run := instance.GetExport("run").Func()
    _, err = run.Call()
    check(err)
}

func check(e error) {
    if e != nil {
        panic(e)
    }
}

Contributing

So far this extension has been written by folks who are primarily Rust programmers, so it's highly likely that there's some faux pas in terms of Go idioms. Feel free to send a PR to help make things more idiomatic if you see something!

To work on this extension locally you'll first want to clone the project:

$ git clone https://github.com/bytecodealliance/wasmtime-go

Next up you'll want to have a local Wasmtime build available.

You'll need to build at least the wasmtime-c-api crate, which, at the time of this writing, would be:

$ cargo build -p wasmtime-c-api

Once you've got that you can set up the environment of this library with:

$ ./ci/local.sh /path/to/wasmtime

This will create a build directory which has the compiled libraries and header files. Next up you can run normal commands such as:

$ go test

And after that you should be good to go!

Documentation

Overview

A WebAssembly runtime for Go powered by Wasmtime.

This package provides everything necessary to compile and execute WebAssembly modules as part of a Go program. Wasmtime is a JIT compiler written in Rust, and can be found at https://github.com/bytecodealliance/wasmtime. This package is a binding to the C API provided by Wasmtime.

The API of this Go package is intended to mirror the Rust API (https://docs.rs/wasmtime) relatively closely, so if you find something is under-documented here then you may have luck consulting the Rust documentation as well. As always though feel free to file any issues at https://github.com/bytecodealliance/wasmtime-go/issues/new.

It's also worth pointing out that the authors of this package up to this point primarily work in Rust, so if you've got suggestions of how to make this package more idiomatic for Go we'd love to hear your thoughts!

Example

An example of instantiating a small wasm module which imports functionality from the host, then calling into wasm which calls back into the host.

// Almost all operations in wasmtime require a contextual `store`
// argument to share, so create that first
store := NewStore(NewEngine())

// Compiling modules requires WebAssembly binary input, but the wasmtime
// package also supports converting the WebAssembly text format to the
// binary format.
wasm, err := Wat2Wasm(`
	  (module
	  (import "" "hello" (func $hello))
	  (func (export "run")
	    (call $hello))
	  )
      `)
check(err)

// Once we have our binary `wasm` we can compile that into a `*Module`
// which represents compiled JIT code.
module, err := NewModule(store, wasm)
check(err)

// Our `hello.wat` file imports one item, so we create that function
// here.
item := WrapFunc(store, func() {
	fmt.Println("Hello from Go!")
})

// Next up we instantiate a module which is where we link in all our
// imports. We've got one import so we pass that in here.
instance, err := NewInstance(module, []*Extern{item.AsExtern()})
check(err)

// After we've instantiated we can lookup our `run` function and call
// it.
run := instance.GetExport("run").Func()
_, err = run.Call()
check(err)
Output:

Hello from Go!
Example (Gcd)

An example of a wasm module which calculates the GCD of two numbers

store := NewStore(NewEngine())
wasm, err := Wat2Wasm(GCD_WAT)
check(err)
module, err := NewModule(store, wasm)
check(err)
instance, err := NewInstance(module, []*Extern{})
check(err)
run := instance.GetExport("gcd").Func()
result, err := run.Call(6, 27)
check(err)
fmt.Printf("gcd(6, 27) = %d\n", result.(int32))
Output:

gcd(6, 27) = 3
Example (Memory)

An example of working with the Memory type to read/write wasm memory.

// Create our `Store` context and then compile a module and create an
// instance from the compiled module all in one go.
wasmtime_store := NewStore(NewEngine())
wasm, err := Wat2Wasm(`
          (module
            (memory (export "memory") 2 3)

            (func (export "size") (result i32) (memory.size))
            (func (export "load") (param i32) (result i32)
              (i32.load8_s (local.get 0))
            )
            (func (export "store") (param i32 i32)
              (i32.store8 (local.get 0) (local.get 1))
            )

            (data (i32.const 0x1000) "\01\02\03\04")
          )
        `)
check(err)
module, err := NewModule(wasmtime_store, wasm)
check(err)
instance, err := NewInstance(module, []*Extern{})
check(err)

// Load up our exports from the instance
memory := instance.GetExport("memory").Memory()
size := instance.GetExport("size").Func()
load := instance.GetExport("load").Func()
store := instance.GetExport("store").Func()

// some helper functions we'll use below
call32 := func(f *Func, args ...interface{}) int32 {
	ret, err := f.Call(args...)
	check(err)
	return ret.(int32)
}
call := func(f *Func, args ...interface{}) {
	_, err := f.Call(args...)
	check(err)
}
assertTraps := func(f *Func, args ...interface{}) {
	_, err := f.Call(args...)
	_, ok := err.(*Trap)
	if !ok {
		panic("expected a trap")
	}
}

// Check the initial memory sizes/contents
assert(memory.Size() == 2)
assert(memory.DataSize() == 0x20000)
buf := memory.UnsafeData()

assert(buf[0] == 0)
assert(buf[0x1000] == 1)
assert(buf[0x1003] == 4)

assert(call32(size) == 2)
assert(call32(load, 0) == 0)
assert(call32(load, 0x1000) == 1)
assert(call32(load, 0x1003) == 4)
assert(call32(load, 0x1ffff) == 0)
assertTraps(load, 0x20000)

// We can mutate memory as well
buf[0x1003] = 5
call(store, 0x1002, 6)
assertTraps(store, 0x20000, 0)

assert(buf[0x1002] == 6)
assert(buf[0x1003] == 5)
assert(call32(load, 0x1002) == 6)
assert(call32(load, 0x1003) == 5)

// And like wasm instructions, we can grow memory
assert(memory.Grow(1))
assert(memory.Size() == 3)
assert(memory.DataSize() == 0x30000)

assert(call32(load, 0x20000) == 0)
call(store, 0x20000, 0)
assertTraps(load, 0x30000)
assertTraps(store, 0x30000, 0)

// Memory can fail to grow
assert(!memory.Grow(1))
assert(memory.Grow(0))

// Ensure that `memory` lives long enough to cover all our usages of
// using its internal buffer we read from `UnsafeData()`
runtime.KeepAlive(memory)

// Finally we can also create standalone memories to get imported by
// wasm modules too.
memorytype := NewMemoryType(Limits{Min: 5, Max: 5})
memory2 := NewMemory(wasmtime_store, memorytype)
assert(memory2.Size() == 5)
assert(!memory2.Grow(1))
assert(memory2.Grow(0))
Output:

Example (Multi)

An example of enabling the multi-value feature of WebAssembly and interacting with multi-value functions.

// Configure our `Store`, but be sure to use a `Config` that enables the
// wasm multi-value feature since it's not stable yet.
config := NewConfig()
config.SetWasmMultiValue(true)
store := NewStore(NewEngineWithConfig(config))

wasm, err := Wat2Wasm(`
	  (module
	    (func $f (import "" "f") (param i32 i64) (result i64 i32))

	    (func $g (export "g") (param i32 i64) (result i64 i32)
	      (call $f (local.get 0) (local.get 1))
	    )

	    (func $round_trip_many
	      (export "round_trip_many")
	      (param i64 i64 i64 i64 i64 i64 i64 i64 i64 i64)
	      (result i64 i64 i64 i64 i64 i64 i64 i64 i64 i64)

	      local.get 0
	      local.get 1
	      local.get 2
	      local.get 3
	      local.get 4
	      local.get 5
	      local.get 6
	      local.get 7
	      local.get 8
	      local.get 9)
	  )
        `)
check(err)
module, err := NewModule(store, wasm)
check(err)

callback := WrapFunc(store, func(a int32, b int64) (int64, int32) {
	return b + 1, a + 1
})

instance, err := NewInstance(module, []*Extern{callback.AsExtern()})
check(err)

g := instance.GetExport("g").Func()

results, err := g.Call(1, 3)
check(err)
arr := results.([]Val)
a := arr[0].I64()
b := arr[1].I32()
fmt.Printf("> %d %d\n", a, b)

assert(a == 4)
assert(b == 2)

round_trip_many := instance.GetExport("round_trip_many").Func()
results, err = round_trip_many.Call(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
check(err)
arr = results.([]Val)

for i := 0; i < len(arr); i++ {
	fmt.Printf(" %d", arr[i].Get())
	assert(arr[i].I64() == int64(i))
}
Output:

> 4 2
 0 1 2 3 4 5 6 7 8 9

Index

Examples

Constants

View Source
const LIMITS_MAX_NONE = 0xffffffff

Value for the Max field in Limits

Variables

This section is empty.

Functions

func ModuleValidate

func ModuleValidate(store *Store, wasm []byte) error

Validates whether `wasm` would be a valid wasm module according to the configuration in `store`

func Wat2Wasm

func Wat2Wasm(wat string) ([]byte, error)

Converts the text format of WebAssembly to the binary format.

Takes the text format in-memory as input, and returns either the binary encoding of the text format or an error if parsing fails.

Types

type AsExtern

type AsExtern interface {
	AsExtern() *Extern
}

type AsExternType

type AsExternType interface {
	AsExternType() *ExternType
}

type Caller

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

func (*Caller) GetExport

func (c *Caller) GetExport(name string) *Extern

Gets an exported item from the caller's module.

May return `nil` if the export doesn't, if it's not a memory, if there isn't a caller, etc.

type Config

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

Configuration of an `Engine` which is used to globally configure things like wasm features and such.

func NewConfig

func NewConfig() *Config

Creates a new `Config` with all default options configured.

func (*Config) CacheConfigLoad added in v0.16.0

func (cfg *Config) CacheConfigLoad(path string) error

Enables compiled code caching for this `Config` using the setting specified in the configuration file `path`.

For more information about caching and configuration options see https://bytecodealliance.github.io/wasmtime/cli-cache.html

func (*Config) CacheConfigLoadDefault added in v0.16.0

func (cfg *Config) CacheConfigLoadDefault() error

Enables compiled code caching for this `Config` using the default settings configuration can be found.

For more information about caching see https://bytecodealliance.github.io/wasmtime/cli-cache.html

func (*Config) SetCraneliftDebugVerifier

func (cfg *Config) SetCraneliftDebugVerifier(enabled bool)

Configures whether the cranelift debug verifier will be active when cranelift is used to compile wasm code.

func (*Config) SetCraneliftOptLevel

func (cfg *Config) SetCraneliftOptLevel(level OptLevel)

Configures the cranelift optimization level for generated code

func (*Config) SetDebugInfo

func (cfg *Config) SetDebugInfo(enabled bool)

Configures whether dwarf debug information for JIT code is enabled

func (*Config) SetInterruptable added in v0.16.0

func (cfg *Config) SetInterruptable(interruptable bool)

Configures whether generated wasm code will be interrupted via interrupt handles.

func (*Config) SetProfiler

func (cfg *Config) SetProfiler(profiler ProfilingStrategy) error

Configures what profiler strategy to use for generated code

func (*Config) SetStrategy

func (cfg *Config) SetStrategy(strat Strategy) error

Configures what compilation strategy is used to compile wasm code

func (*Config) SetWasmBulkMemory

func (cfg *Config) SetWasmBulkMemory(enabled bool)

Configures whether the wasm bulk memory proposal is enabled

func (*Config) SetWasmMultiValue

func (cfg *Config) SetWasmMultiValue(enabled bool)

Configures whether the wasm multi value proposal is enabled

func (*Config) SetWasmReferenceTypes

func (cfg *Config) SetWasmReferenceTypes(enabled bool)

Configures whether the wasm reference types proposal is enabled

func (*Config) SetWasmSIMD

func (cfg *Config) SetWasmSIMD(enabled bool)

Configures whether the wasm SIMD proposal is enabled

func (*Config) SetWasmThreads

func (cfg *Config) SetWasmThreads(enabled bool)

Configures whether the wasm threads proposal is enabled

type Engine

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

An instance of a wasmtime engine which is used to create a `Store`.

Engines are a form of global configuration for wasm compilations and modules and such.

func NewEngine

func NewEngine() *Engine

Creates a new `Engine` with default configuration.

func NewEngineWithConfig

func NewEngineWithConfig(config *Config) *Engine

Creates a new `Engine` with the `Config` provided

Note that once a `Config` is passed to this method it cannot be used again.

type Error

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

func (*Error) Error

func (e *Error) Error() string

type ExportType

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

func NewExportType

func NewExportType(name string, ty AsExternType) *ExportType

Creates a new `ExportType` with the `name` and the type provided.

func (*ExportType) Name

func (ty *ExportType) Name() string

Returns the name in the module this export type is exporting

func (*ExportType) Type

func (ty *ExportType) Type() *ExternType

Returns the type of item this export type expects

type Extern

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

func (*Extern) AsExtern

func (e *Extern) AsExtern() *Extern

func (*Extern) Func

func (e *Extern) Func() *Func

Returns a Func if this export is a function or nil otherwise

func (*Extern) Global

func (e *Extern) Global() *Global

Returns a Global if this export is a global or nil otherwise

func (*Extern) Memory

func (e *Extern) Memory() *Memory

Returns a Memory if this export is a memory or nil otherwise

func (*Extern) Table

func (e *Extern) Table() *Table

Returns a Table if this export is a table or nil otherwise

func (*Extern) Type

func (e *Extern) Type() *ExternType

Returns the type of this export

type ExternType

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

func (*ExternType) AsExternType

func (ty *ExternType) AsExternType() *ExternType

Returns this type itself

func (*ExternType) FuncType

func (ty *ExternType) FuncType() *FuncType

Returns the underlying `FuncType` for this `ExternType` if it's a function type. Otherwise returns `nil`.

func (*ExternType) GlobalType

func (ty *ExternType) GlobalType() *GlobalType

Returns the underlying `GlobalType` for this `ExternType` if it's a function type. Otherwise returns `nil`.

func (*ExternType) MemoryType

func (ty *ExternType) MemoryType() *MemoryType

Returns the underlying `MemoryType` for this `ExternType` if it's a function type. Otherwise returns `nil`.

func (*ExternType) TableType

func (ty *ExternType) TableType() *TableType

Returns the underlying `TableType` for this `ExternType` if it's a function type. Otherwise returns `nil`.

type Frame

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

func (*Frame) FuncIndex

func (f *Frame) FuncIndex() uint32

Returns the function index in the wasm module that this frame represents

func (*Frame) FuncName

func (f *Frame) FuncName() *string

Returns the name, if available, for this frame's function

func (*Frame) FuncOffset added in v0.16.0

func (f *Frame) FuncOffset() uint

Returns offset of this frame's instruction into the original function

func (*Frame) ModuleName

func (f *Frame) ModuleName() *string

Returns the name, if available, for this frame's module

func (*Frame) ModuleOffset added in v0.16.0

func (f *Frame) ModuleOffset() uint

Returns offset of this frame's instruction into the original module

type Func

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

func NewFunc

func NewFunc(
	store *Store,
	ty *FuncType,
	f func(*Caller, []Val) ([]Val, *Trap),
) *Func

Creates a new `Func` with the given `ty` which, when called, will call `f`

The `ty` given is the wasm type signature of the `Func` to create. When called the `f` callback receives two arguments. The first is a `Caller` to learn information about the calling context and the second is a list of arguments represented as a `Val`. The parameters are guaranteed to match the parameters types specified in `ty`.

The `f` callback is expected to produce one of two values. Results can be returned as an array of `[]Val`. The number and types of these results much match the `ty` given, otherwise the program will panic. The `f` callback can also produce a trap which will trigger trap unwinding in wasm, and the trap will be returned to the original caller.

If the `f` callback panics then the panic will be propagated to the caller as well.

func WrapFunc

func WrapFunc(
	store *Store,
	f interface{},
) *Func

Wraps a native Go function, `f`, as a wasm `Func`.

This function differs from `NewFunc` in that it will determine the type signature of the wasm function given the input value `f`. The `f` value provided must be a Go function. It may take any number of the following types as arguments:

`int32` - a wasm `i32`

`int64` - a wasm `i64`

`float32` - a wasm `f32`

`float64` - a wasm `f32`

`*Caller` - information about the caller's instance

The Go function may return any number of values. It can return any number of primitive wasm values (integers/floats), and the last return value may optionally be `*Trap`. If a `*Trap` returned is `nil` then the other values are returned from the wasm function. Otherwise the `*Trap` is returned and it's considered as if the host function trapped.

If the function `f` panics then the panic will be propagated to the caller.

func (*Func) AsExtern

func (f *Func) AsExtern() *Extern

func (*Func) Call

func (f *Func) Call(args ...interface{}) (interface{}, error)

Invokes this function with the provided `args`.

This variadic function must be invoked with the correct number and type of `args` as specified by the type of this function. This property is checked at runtime. Each `args` may have one of the following types:

`int32` - a wasm `i32`

`int64` - a wasm `i64`

`float32` - a wasm `f32`

`float64` - a wasm `f64`

`Val` - correspond to a wasm value

Any other types of `args` will cause this function to panic.

This function will have one of three results:

1. If the function returns successfully, then the `interface{}` return argument will be the result of the function. If there were 0 results then this value is `nil`. If there was one result then this is that result. Otherwise if there were multiple results then `[]Val` is returned.

2. If this function invocation traps, then the returned `interface{}` value will be `nil` and a non-`nil` `*Trap` will be returned with information about the trap that happened.

3. If a panic in Go ends up happening somewhere, then this function will panic.

func (*Func) ParamArity

func (f *Func) ParamArity() int

Returns the numer of parameters this function expects

func (*Func) ResultArity

func (f *Func) ResultArity() int

Returns the numer of results this function produces

func (*Func) Type

func (f *Func) Type() *FuncType

Returns the type of this func

type FuncType

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

func NewFuncType

func NewFuncType(params, results []*ValType) *FuncType

Creates a new `FuncType` with the `kind` provided

func (*FuncType) AsExternType

func (ty *FuncType) AsExternType() *ExternType

Converts this type to an instance of `ExternType`

func (*FuncType) Params

func (ty *FuncType) Params() []*ValType

Returns the parameter types of this function type

func (*FuncType) Results

func (ty *FuncType) Results() []*ValType

Returns the result types of this function type

type Global

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

func NewGlobal

func NewGlobal(
	store *Store,
	ty *GlobalType,
	val Val,
) (*Global, error)

Creates a new `Global` in the given `Store` with the specified `ty` and initial value `val`.

func (*Global) AsExtern

func (g *Global) AsExtern() *Extern

func (*Global) Get

func (g *Global) Get() Val

Gets the value of this global

func (*Global) Set

func (g *Global) Set(val Val) error

Sets the value of this global

func (*Global) Type

func (g *Global) Type() *GlobalType

Returns the type of this global

type GlobalType

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

func NewGlobalType

func NewGlobalType(content *ValType, mutable bool) *GlobalType

Creates a new `GlobalType` with the `kind` provided and whether it's `mutable` or not

func (*GlobalType) AsExternType

func (ty *GlobalType) AsExternType() *ExternType

Converts this type to an instance of `ExternType`

func (*GlobalType) Content

func (ty *GlobalType) Content() *ValType

Returns the type of value stored in this global

func (*GlobalType) Mutable

func (ty *GlobalType) Mutable() bool

Returns whether this global type is mutable or not

type ImportType

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

func NewImportType

func NewImportType(module, name string, ty AsExternType) *ImportType

Creates a new `ImportType` with the given `module` and `name` and the type provided.

func (*ImportType) Module

func (ty *ImportType) Module() string

Returns the name in the module this import type is importing

func (*ImportType) Name

func (ty *ImportType) Name() string

Returns the name in the module this import type is importing

func (*ImportType) Type

func (ty *ImportType) Type() *ExternType

Returns the type of item this import type expects

type Instance

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

func NewInstance

func NewInstance(module *Module, imports []*Extern) (*Instance, error)

Instantiates a WebAssembly `module` with the `imports` provided.

This function will attempt to create a new wasm instance given the provided imports. This can fail if the wrong number of imports are specified, the imports aren't of the right type, or for other resource-related issues.

This will also run the `start` function of the instance, returning an error if it traps.

func (*Instance) Exports

func (i *Instance) Exports() []*Extern

Returns a list of exports from this instance.

Each export is returned as a `*Extern` and lines up with the exports list of the associated `Module`.

func (*Instance) GetExport

func (i *Instance) GetExport(name string) *Extern

Attempts to find an export on this instance by `name`

May return `nil` if this instance has no export named `name`

type InterruptHandle added in v0.16.0

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

An `InterruptHandle` is used to interrupt the execution of currently running wasm code.

For more information see https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Store.html#method.interrupt_handle

func (*InterruptHandle) Interrupt added in v0.16.0

func (i *InterruptHandle) Interrupt()

Interrupts currently executing WebAssembly code, if it's currently running, or interrupts wasm the next time it starts running.

For more information see https://bytecodealliance.github.io/wasmtime/api/wasmtime/struct.Store.html#method.interrupt_handle

type Limits

type Limits struct {
	// The minimum size of this resource, in units specified by the resource
	// itself.
	Min uint32
	// The maximum size of this resource, in units specified by the resource
	// itself.
	//
	// A value of LIMITS_MAX_NONE will mean that there is no maximum.
	Max uint32
}

Resource limits specified for a TableType and MemoryType

type Linker

type Linker struct {
	Store *Store
	// contains filtered or unexported fields
}
Example
store := NewStore(NewEngine())

// Compile two wasm modules where the first references the second
wasm1, err := Wat2Wasm(`
	    (module
		(import "wasm2" "double" (func $double (param i32) (result i32)))
		(func (export "double_and_add") (param i32 i32) (result i32)
		  local.get 0
		  call $double
		  local.get 1
		  i32.add)
	    )
	`)
check(err)

wasm2, err := Wat2Wasm(`
	    (module
		(func (export "double") (param i32) (result i32)
		  local.get 0
		  i32.const 2
		  i32.mul)
	    )
	`)
check(err)

// Next compile both modules
module1, err := NewModule(store, wasm1)
check(err)
module2, err := NewModule(store, wasm2)
check(err)

linker := NewLinker(store)

// The second module is instantiated first since it has no imports, and
// then we insert the instance back into the linker under the name
// the first module expects.
instance2, err := linker.Instantiate(module2)
check(err)
err = linker.DefineInstance("wasm2", instance2)
check(err)

// And now we can instantiate our first module, executing the result
// afterwards
instance1, err := linker.Instantiate(module1)
check(err)
double_and_add := instance1.GetExport("double_and_add").Func()
result, err := double_and_add.Call(2, 3)
check(err)
fmt.Print(result.(int32))
Output:

7

func NewLinker

func NewLinker(store *Store) *Linker

func (*Linker) AllowShadowing

func (l *Linker) AllowShadowing(allow bool)

Configures whether names can be redefined after they've already been defined in this linker.

func (*Linker) Define

func (l *Linker) Define(module, name string, item AsExtern) error

Defines a new item in this linker with the given module/name pair. Returns an error if shadowing is disallowed and the module/name is already defined.

func (*Linker) DefineFunc

func (l *Linker) DefineFunc(module, name string, f interface{}) error

Convenience wrapper to calling Define and WrapFunc.

Returns an error if shadowing is disabled and the name is already defined.

func (*Linker) DefineInstance

func (l *Linker) DefineInstance(module string, instance *Instance) error

Defines all exports of an instance provided under the module name provided.

Returns an error if shadowing is disabled and names are already defined.

func (*Linker) DefineWasi

func (l *Linker) DefineWasi(instance *WasiInstance) error

Links a WASI module into this linker, ensuring that all exported functions are available for linking.

Returns an error if shadowing is disabled and names are already defined.

func (*Linker) Instantiate

func (l *Linker) Instantiate(module *Module) (*Instance, error)

Instantates a module with all imports defined in this linker.

Returns an error if the instance's imports couldn't be satisfied, had the wrong types, or if a trap happened executing the start function.

type Memory

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

func NewMemory

func NewMemory(store *Store, ty *MemoryType) *Memory

Creates a new `Memory` in the given `Store` with the specified `ty`.

func (*Memory) AsExtern

func (m *Memory) AsExtern() *Extern

func (*Memory) Data

func (m *Memory) Data() unsafe.Pointer

Returns the raw pointer in memory of where this memory starts

func (*Memory) DataSize

func (m *Memory) DataSize() uintptr

Returns the size, in bytes, that `Data()` is valid for

func (*Memory) Grow

func (m *Memory) Grow(delta uint) bool

Grows this memory by `delta` pages

func (*Memory) Size

func (m *Memory) Size() uint32

Returns the size, in wasm pages, of this memory

func (*Memory) Type

func (m *Memory) Type() *MemoryType

Returns the type of this memory

func (*Memory) UnsafeData added in v0.16.2

func (m *Memory) UnsafeData() []byte

Returns the raw memory backed by this `Memory` as a byte slice (`[]byte`).

This is not a safe method to call, hence the "unsafe" in the name. The byte slice returned from this function is not managed by the Go garbage collector. You need to ensure that `m`, the original `Memory`, lives longer than the `[]byte` returned.

Note that you may need to use `runtime.KeepAlive` to keep the original memory `m` alive for long enough while you're using the `[]byte` slice. If the `[]byte` slice is used after `m` is GC'd then that is undefined behavior.

type MemoryType

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

func NewMemoryType

func NewMemoryType(limits Limits) *MemoryType

Creates a new `MemoryType` with the `limits` on size provided

func (*MemoryType) AsExternType

func (ty *MemoryType) AsExternType() *ExternType

Converts this type to an instance of `ExternType`

func (*MemoryType) Limits

func (ty *MemoryType) Limits() Limits

Returns the limits on the size of this memory type

type Module

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

func NewModule

func NewModule(store *Store, wasm []byte) (*Module, error)

Compiles a new `Module` from the `wasm` provided with the given configuration in `store`.

func NewModuleFromFile

func NewModuleFromFile(store *Store, file string) (*Module, error)

Reads the contents of the `file` provided and interprets them as either the text format or the binary format for WebAssembly.

Afterwards delegates to the `NewModule` constructor with the contents read.

func (*Module) Exports

func (m *Module) Exports() []*ExportType

Returns a list of `ExportType` items which are the items that will be exported by this module after instantiation.

func (*Module) Imports

func (m *Module) Imports() []*ImportType

Returns a list of `ImportType` items which are the items imported by this module and are required for instantiation.

type OptLevel

type OptLevel C.wasmtime_opt_level_t

What degree of optimization wasmtime will perform on generated machine code

const (
	// No optimizations will be performed
	OPT_LEVEL_NONE OptLevel = C.WASMTIME_OPT_LEVEL_NONE
	// Machine code will be optimized to be as fast as possible
	OPT_LEVEL_SPEED OptLevel = C.WASMTIME_OPT_LEVEL_SPEED
	// Machine code will be optimized for speed, but also optimized
	// to be small, sometimes at the cost of speed.
	OPT_LEVEL_SPEED_AND_SIZE OptLevel = C.WASMTIME_OPT_LEVEL_SPEED_AND_SIZE
)

type ProfilingStrategy

type ProfilingStrategy C.wasmtime_profiling_strategy_t

What sort of profiling to enable, if any.

const (
	// No profiler will be used
	PROFILING_STRATEGY_NONE ProfilingStrategy = C.WASMTIME_PROFILING_STRATEGY_NONE
	// The "jitdump" linux support will be used
	PROFILING_STRATEGY_JITDUMP ProfilingStrategy = C.WASMTIME_PROFILING_STRATEGY_JITDUMP
)

type Store

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

A `Store` is a general group of wasm instances, and many objects must all be created with and reference the same `Store`

func NewStore

func NewStore(engine *Engine) *Store

Creates a new `Store` from the configuration provided in `engine`

func (*Store) InterruptHandle added in v0.16.0

func (store *Store) InterruptHandle() (*InterruptHandle, error)

type Strategy

type Strategy C.wasmtime_strategy_t

Compilation strategies for wasmtime

const (
	// Wasmtime will automatically pick an appropriate compilation strategy
	STRATEGY_AUTO Strategy = C.WASMTIME_STRATEGY_AUTO
	// Force wasmtime to use the Cranelift backend
	STRATEGY_CRANELIFT Strategy = C.WASMTIME_STRATEGY_CRANELIFT
	// Force wasmtime to use the lightbeam backend
	STRATEGY_LIGHTBEAM Strategy = C.WASMTIME_STRATEGY_LIGHTBEAM
)

type Table

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

func NewTable added in v0.16.2

func NewTable(store *Store, ty *TableType, init *Func) (*Table, error)

Creates a new `Table` in the given `Store` with the specified `ty`.

The `ty` must be a `funcref` table and `init` is the initial value for all table slots, and is allowed to be `nil`.

func (*Table) AsExtern

func (t *Table) AsExtern() *Extern

func (*Table) Get added in v0.16.2

func (t *Table) Get(idx uint32) (*Func, error)

Gets an item from this table from the specified index.

Returns an error if the index is out of bounds, or returns a function (which may be `nil`) if the index is in bounds corresponding to the entry at the specified index.

func (*Table) Grow added in v0.16.2

func (t *Table) Grow(delta uint32, init *Func) (uint32, error)

Grows this funcref table by the number of units specified, using the specified initializer value for new slots.

Note that `init` is allowed to be `nil`.

Returns an error if the table failed to grow, or the previous size of the table if growth was successful.

func (*Table) Set added in v0.16.2

func (t *Table) Set(idx uint32, val *Func) error

Sets an item in this table at the specified index.

Returns an error if the index is out of bounds.

func (*Table) Size

func (t *Table) Size() uint32

Returns the size of this table in units of elements.

func (*Table) Type

func (t *Table) Type() *TableType

Returns the underlying type of this table

type TableType

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

func NewTableType

func NewTableType(element *ValType, limits Limits) *TableType

Creates a new `TableType` with the `element` type provided as well as `limits` on its size.

func (*TableType) AsExternType

func (ty *TableType) AsExternType() *ExternType

Converts this type to an instance of `ExternType`

func (*TableType) Element

func (ty *TableType) Element() *ValType

Returns the type of value stored in this table

func (*TableType) Limits

func (ty *TableType) Limits() Limits

Returns limits on the size of this table type

type Trap

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

func NewTrap

func NewTrap(store *Store, message string) *Trap

Creates a new `Trap` with the `name` and the type provided.

func (*Trap) Error

func (t *Trap) Error() string

func (*Trap) Frames

func (t *Trap) Frames() []*Frame

Returns the wasm function frames that make up this trap

func (*Trap) Message

func (t *Trap) Message() string

Returns the name in the module this export type is exporting

type Val

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

func ValF32

func ValF32(val float32) Val

func ValF64

func ValF64(val float64) Val

func ValI32

func ValI32(val int32) Val

func ValI64

func ValI64(val int64) Val

func (Val) F32

func (v Val) F32() float32

Returns the underlying 32-bit float if this is an `f32`, or panics.

func (Val) F64

func (v Val) F64() float64

Returns the underlying 64-bit float if this is an `f64`, or panics.

func (Val) Get

func (v Val) Get() interface{}

Returns the underlying 64-bit float if this is an `f64`, or panics.

func (Val) I32

func (v Val) I32() int32

Returns the underlying 32-bit integer if this is an `i32`, or panics.

func (Val) I64

func (v Val) I64() int64

Returns the underlying 64-bit integer if this is an `i64`, or panics.

func (Val) Kind

func (v Val) Kind() ValKind

Returns the kind of value that this `Val` contains.

type ValKind

type ValKind C.wasm_valkind_t

Enumeration of different kinds of value types

const (
	KindI32     ValKind = C.WASM_I32
	KindI64     ValKind = C.WASM_I64
	KindF32     ValKind = C.WASM_F32
	KindF64     ValKind = C.WASM_F64
	KindAnyref  ValKind = C.WASM_ANYREF
	KindFuncref ValKind = C.WASM_FUNCREF
)

func (ValKind) String

func (ty ValKind) String() string

Renders this kind as a string, similar to the `*.wat` format

type ValType

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

func NewValType

func NewValType(kind ValKind) *ValType

Creates a new `ValType` with the `kind` provided

func (*ValType) Kind

func (ty *ValType) Kind() ValKind

Returns the corresponding `ValKind` for this `ValType`

func (*ValType) String

func (ty *ValType) String() string

Converts this `ValType` into a string according to the string representation of `ValKind`.

type WasiConfig

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

func NewWasiConfig

func NewWasiConfig() *WasiConfig

func (*WasiConfig) InheritArgv

func (c *WasiConfig) InheritArgv()

func (*WasiConfig) InheritEnv

func (c *WasiConfig) InheritEnv()

func (*WasiConfig) InheritStderr

func (c *WasiConfig) InheritStderr()

func (*WasiConfig) InheritStdin

func (c *WasiConfig) InheritStdin()

func (*WasiConfig) InheritStdout

func (c *WasiConfig) InheritStdout()

func (*WasiConfig) PreopenDir

func (c *WasiConfig) PreopenDir(path, guest_path string) error

func (*WasiConfig) SetArgv

func (c *WasiConfig) SetArgv(argv []string)

func (*WasiConfig) SetEnv

func (c *WasiConfig) SetEnv(keys, values []string)

func (*WasiConfig) SetStderrFile

func (c *WasiConfig) SetStderrFile(path string) error

func (*WasiConfig) SetStdinFile

func (c *WasiConfig) SetStdinFile(path string) error

func (*WasiConfig) SetStdoutFile

func (c *WasiConfig) SetStdoutFile(path string) error

type WasiInstance

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

func NewWasiInstance

func NewWasiInstance(store *Store, config *WasiConfig, name string) (*WasiInstance, error)

Creates a new instance of WASI with the given configuration.

The version of WASI must be explicitly requested via `name`.

func (*WasiInstance) BindImport

func (i *WasiInstance) BindImport(imp *ImportType) *Extern

Attempts to bind the `imp` import provided, returning an Extern suitable for satisfying the import if one can be found.

If `imp` isn't defined by this instance of WASI then `nil` is returned.

Jump to

Keyboard shortcuts

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