Documentation
¶
Overview ¶
Package exec provides functions for executing WebAssembly bytecode.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSignatureMismatch is the error value used while trapping the VM when // a signature mismatch between the table entry and the type entry is found // in a call_indirect operation. ErrSignatureMismatch = errors.New("exec: signature mismatch in call_indirect") // ErrUndefinedElementIndex is the error value used while trapping the VM when // an invalid index to the module's table space is used as an operand to // call_indirect ErrUndefinedElementIndex = errors.New("exec: undefined element index") )
var ( // ErrMultipleLinearMemories is returned by (*VM).NewVM when the module // has more then one entries in the linear memory space. ErrMultipleLinearMemories = errors.New("exec: more than one linear memories in module") // ErrInvalidArgumentCount is returned by (*VM).ExecCode when an invalid // number of arguments to the WebAssembly function are passed to it. ErrInvalidArgumentCount = errors.New("exec: invalid number of arguments to function") )
var ErrOutOfBoundsMemoryAccess = errors.New("exec: out of bounds memory access")
ErrOutOfBoundsMemoryAccess is the error value used while trapping the VM when it detects an out of bounds access to the linear memory.
var ErrUnreachable = errors.New("exec: reached unreachable")
ErrUnreachable is the error value used while trapping the VM when an unreachable operator is reached during execution.
Functions ¶
This section is empty.
Types ¶
type InvalidFunctionIndexError ¶
type InvalidFunctionIndexError int64
InvalidFunctionIndexError is returned by (*VM).ExecCode when the function index provided is invalid.
func (InvalidFunctionIndexError) Error ¶
func (e InvalidFunctionIndexError) Error() string
type InvalidReturnTypeError ¶
type InvalidReturnTypeError int8
InvalidReturnTypeError is returned by (*VM).ExecCode when the module specifies an invalid return type value for the executed function.
func (InvalidReturnTypeError) Error ¶
func (e InvalidReturnTypeError) Error() string
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process is a proxy passed to host functions in order to access things such as memory and control.
func NewProcess ¶
NewProcess creates a VM interface object for host functions
func (*Process) ReadAt ¶
ReadAt implements the ReaderAt interface: it copies into p the content of memory at offset off.
type VM ¶
type VM struct {
// RecoverPanic controls whether the `ExecCode` method
// recovers from a panic and returns it as an error
// instead.
// A panic can occur either when executing an invalid VM
// or encountering an invalid instruction, e.g. `unreachable`.
RecoverPanic bool
// contains filtered or unexported fields
}
VM is the execution context for executing WebAssembly bytecode.
Example (Add) ¶
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"reflect"
"github.com/go-interpreter/wagon/exec"
"github.com/go-interpreter/wagon/wasm"
)
func main() {
raw, err := compileWast2Wasm("testdata/add-ex-main.wast")
if err != nil {
log.Fatalf("could not compile wast file: %v", err)
}
m, err := wasm.ReadModule(bytes.NewReader(raw), func(name string) (*wasm.Module, error) {
// ReadModule takes as a second argument an optional "importer" function
// that is supposed to locate and import other modules when some module is
// requested (by name.)
// Theoretically, a general "importer" function not unlike the Python's 'import'
// mechanism (that tries to locate and import modules from a $PYTHONPATH)
// could be devised.
switch name {
case "add":
raw, err := compileWast2Wasm("testdata/add-ex.wast")
if err != nil {
return nil, fmt.Errorf("could not compile wast file hosting %q: %v", name, err)
}
add, err := wasm.ReadModule(bytes.NewReader(raw), nil)
if err != nil {
return nil, fmt.Errorf("could not read wasm %q module: %v", name, err)
}
return add, nil
case "go":
// create a whole new module, called "go", from scratch.
// this module will contain one exported function "print",
// implemented itself in pure Go.
print := func(proc *exec.Process, v int32) {
fmt.Printf("result = %v\n", v)
}
m := wasm.NewModule()
m.Types = &wasm.SectionTypes{
Entries: []wasm.FunctionSig{
{
Form: 0, // value for the 'func' type constructor
ParamTypes: []wasm.ValueType{wasm.ValueTypeI32},
},
},
}
m.FunctionIndexSpace = []wasm.Function{
{
Sig: &m.Types.Entries[0],
Host: reflect.ValueOf(print),
Body: &wasm.FunctionBody{}, // create a dummy wasm body (the actual value will be taken from Host.)
},
}
m.Export = &wasm.SectionExports{
Entries: map[string]wasm.ExportEntry{
"print": {
FieldStr: "print",
Kind: wasm.ExternalFunction,
Index: 0,
},
},
}
return m, nil
}
return nil, fmt.Errorf("module %q unknown", name)
})
if err != nil {
log.Fatalf("could not read module: %v", err)
}
vm, err := exec.NewVM(m)
if err != nil {
log.Fatalf("could not create wagon vm: %v", err)
}
const fct1 = 2 // index of function fct1
out, err := vm.ExecCode(fct1)
if err != nil {
log.Fatalf("could not execute fct1(): %v", err)
}
fmt.Printf("fct1() -> %v\n", out)
const fct2 = 3 // index of function fct2
out, err = vm.ExecCode(fct2, 40, 6)
if err != nil {
log.Fatalf("could not execute fct2(40, 6): %v", err)
}
fmt.Printf("fct2() -> %v\n", out)
const fct3 = 4 // index of function fct3
out, err = vm.ExecCode(fct3, 42, 42)
if err != nil {
log.Fatalf("could not execute fct3(42, 42): %v", err)
}
fmt.Printf("fct3() -> %v\n", out)
}
// compileWast2Wasm fakes a compilation pass from WAST to WASM.
//
// When wagon gets a WAST parser, this function will be running an actual compilation.
// See: https://github.com/go-interpreter/wagon/issues/34
func compileWast2Wasm(fname string) ([]byte, error) {
switch fname {
case "testdata/add-ex.wast":
// obtained by running:
// $> wat2wasm -v -o add-ex.wasm add-ex.wast
return ioutil.ReadFile("testdata/add-ex.wasm")
case "testdata/add-ex-main.wast":
// obtained by running:
// $> wat2wasm -v -o add-ex-main.wasm add-ex-main.wast
return ioutil.ReadFile("testdata/add-ex-main.wasm")
}
return nil, fmt.Errorf("unknown wast test file %q", fname)
}
Output: fct1() -> 42 fct2() -> 46 result = 84 fct3() -> <nil>
func NewVM ¶
NewVM creates a new VM from a given module. If the module defines a start function, it will be executed.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
compile
Package compile is used internally by wagon to convert standard structured WebAssembly bytecode into an unstructured form suitable for execution by it's VM.
|
Package compile is used internally by wagon to convert standard structured WebAssembly bytecode into an unstructured form suitable for execution by it's VM. |