🐹🕸️ WebAssembly runtime for Go

Overview

A complete and mature WebAssembly runtime for Go based on Wasmer.

Features

  • Easy to use: The wasmer API mimics the standard WebAssembly API,
  • Fast: wasmer executes the WebAssembly modules as fast as possible, close to native speed,
  • Safe: All calls to WebAssembly will be fast, but more importantly, completely safe and sandboxed.

Documentation: browse the detailed API documentation full of examples.

Examples as tutorials: browse the examples/ directory, it's the best place for a complete introduction!

Install

To install the library, follow the classical:

$ go get github.com/wasmerio/wasmer-go/wasmer

And you're ready to get fun!

Supported platforms

This library embeds the Wasmer runtime compiled as shared library objects, and so uses cgo to consume it. A set of precompiled shared library objects are provided. Thus this library works (and is tested) on the following platforms:

Platform Architecture Triple Status
Linux amd64 x86_64-unknown-linux-gnu
aarch64 aarch64-unknown-linux-gnu
Darwin amd64 x86_64-apple-darwin
aarch64 aarch64-apple-darwin
Windows amd64 x86_64-pc-windows-msvc
What to do if your platform is missing?

Up to now, there is no script to automate that process. We are working on it.

Here are the steps to do that manually:

$ # Build the new Wasmer C API shared object library.
$ cargo build --release
$
$ # Configure cgo.
$ export CGO_CFLAGS="-I$(pwd)/wasmer/packaged/include/"
$ export CGO_LDFLAGS="-Wl,-rpath,$(pwd)/target/release/ -L$(pwd)/target/release/ -lwasmer_go"
$
$ # Run the tests.
$ just test -tags custom_wasmer_runtime

Examples

We highly recommend to read the examples/ directory, which contains a sequence of examples/tutorials. It's the best place to learn by reading examples.

But for the most eager of you, there is a quick toy program in examples/appendices/simple.go, written in Rust:

#[no_mangle]
pub extern "C" fn sum(x: i32, y: i32) -> i32 {
    x + y
}

After compilation to WebAssembly, the examples/appendices/simple.wasm binary is generated.

Then, we can execute it in Go:

package main

import (
	"fmt"
	"io/ioutil"
	wasmer "github.com/wasmerio/wasmer-go/wasmer"
)

func main() {
    wasmBytes, _ := ioutil.ReadFile("simple.wasm")

    engine := wasmer.NewEngine()
    store := wasmer.NewStore(engine)

    // Compiles the module
    module, _ := wasmer.NewModule(store, wasmBytes)

    // Instantiates the module
    importObject := wasmer.NewImportObject()
    instance, _ := wasmer.NewInstance(module, importObject)

    // Gets the `sum` exported function from the WebAssembly instance.
    sum, _ := instance.Exports.GetFunction("sum")

    // Calls that exported function with Go standard values. The WebAssembly
    // types are inferred and values are casted automatically.
    result, _ := sum(5, 37)

    fmt.Println(result) // 42!
}

And then, finally, enjoy by running:

$ go run examples/appendices/simple.go

Testing

Run the tests with the following command:

$ just test

What is WebAssembly?

Quoting the WebAssembly site:

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

About speed:

WebAssembly aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.

About safety:

WebAssembly describes a memory-safe, sandboxed execution environment […].

License

The entire project is under the MIT License. Please read the LICENSE file.

Issues
  • Error: UnableToCreateMemory

    Error: UnableToCreateMemory

    Summary

    When I iteratively create an instance of a module and then close it, I get an UnableToCreateMemory error.

    Additional details

    Here is the code I'm running:

    package main
    
    import (
    	"fmt"
    	wasm "github.com/wasmerio/go-ext-wasm/wasmer"
    )
    
    func main() {
    	bytes, err := wasm.ReadBytes("./simple.wasm")
    	if err != nil { panic(err) }
    
    	module, err := wasm.Compile(bytes)
    	if err != nil { panic(err) }
    	defer module.Close()
    
    	for i:=0; i<1000000; i++ {
    		fmt.Println(i)
    
    		instance, err := module.Instantiate()
    		if err != nil { panic(err) }
    		instance.Close()
    	}
    }
    

    For reference, here is the body of the simple.wasm file in base64 encoding, but I'd assume the results will be similar with any wasm binary.

    AGFzbQEAAAABBwFgAn9/AX8DAgEABAUBcAEBAQUDAQAQBhECfwBBgIDAAAt/AEGAgMAACwdHBQZtZW1vcnkCABlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALX19oZWFwX2Jhc2UDAApfX2RhdGFfZW5kAwEDc3VtAAAJAQAKCQEHACAAIAFqCw==
    

    Here is the tail of the output that I get:

    32723
    32724
    32725
    32726
    panic: Failed to instantiate the module:
        link error: unable to create memory: UnableToCreateMemory
    
    goroutine 1 [running]:
    main.main()
    	/demo/src/hello/hello.go:20 +0x250
    exit status 2
    
    

    The iteration count at which it fails (the last printed number) is non-deterministic, it varies a bit between re-runs.

    I must be doing something wrong, can you help find the issue?

    ❓ question 
    opened by zupa-hu 32
  • feat(wasmexec) New package: `wasmexec`

    feat(wasmexec) New package: `wasmexec`

    This package aims at containing a collection of host functions for multiple hosts, to support WebAssembly modules compiled by the TinyGo and the Go compilers.

    For the moment, only the Go host is supported, i.e. it's Go host functions implementations. Host functions have empty implementation.

    In the future, it will contain real implementations, and it will be extended to a Rust, Python, PHP, Ruby implementations.

    I wonder though if we should support host functions required by the Go compiler. It's really focused on JavaScript, plus it is experimental. cc @MarkMcCaskey @syrusakbary

    🎉 enhancement 📦 component-extension 🧪 tests 
    opened by Hywan 22
  • Problem while doing go get

    Problem while doing go get

    Summary

    I tried doing go get github.com/wasmerio/go-ext-wasm/wasmer

    but it throws me error:

    ../go/src/github.com/wasmerio/go-ext-wasm/wasmer/bridge.go:162:87: cannot use (*_Ctype_struct___13)(instanceContext) (type *_Ctype_struct___13) as type *_Ctype_struct___16 in argument to _Cfunc_wasmer_instance_context_data_get
    

    Additional details

    My go env

    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/ubuntu/.cache/go-build"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/ubuntu/go"
    GOPROXY=""
    GORACE=""
    GOROOT="/usr/local/go"
    GOTMPDIR=""
    GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    CC="gcc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD=""
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build913563706=/tmp/go-build -gno-record-gcc-switches"
    

    Initially, I was getting error:

    [email protected]:~/1$ go get github.com/wasmerio/go-ext-wasm/wasmer
    # github.com/wasmerio/go-ext-wasm/wasmer
    exec: "gcc": executable file not found in $PATH
    

    Than I did sudo apt install gcc and installed gcc.

    Post that the go get for wasmer is giving mentioned error.

    Any pointer on what might have gone wrong?

    ❓ question 
    opened by kleash 19
  • int64 param not working for imported functions

    int64 param not working for imported functions

    Describe the bug

    I have a wasm module that imports a function ext_print_num that takes an int64 parameter. However when I try to implement it, I get an error saying "conflicting types for ext_print_num".

    Maybe this is an issue with int64? My other import functions that accept int32 all work perfectly.

    Steps to reproduce

    package main
    
    // extern void ext_print_num(void *context, int64_t data);
    import "C"
    
    //export ext_print_num
    func ext_print_num(context unsafe.Pointer, data int64) {
    	return
    }
    
    func main() {
    	bytes, err := wasm.ReadBytes("mymodule.wasm")
    	if err != nil {
    		return nil, err
    	}
    	
    	imports, err := wasm.NewImports().Append("ext_print_num", ext_print_num, C.ext_print_num)
    	if err != nil {
    		return nil, err
    	}
    
    	instance, err := wasm.NewInstanceWithImports(bytes, imports)
    	if err != nil {
    		return nil, err
    	}
    	defer instance.Close()
    }
    

    the full code is here: https://github.com/ChainSafe/gossamer/blob/elizabeth/wasmer/runtime/wasmer.go

    Expected behavior

    I wouldn't expect an error since the types should match.

    Actual behavior

    In file included from _cgo_export.c:4:0:
    cgo-gcc-export-header-prolog:58:13: error: conflicting types for ‘ext_print_num’
    In file included from _cgo_export.c:4:0:
    wasmer.go:9:14: note: previous declaration of ‘ext_print_num’ was here
    _cgo_export.c:176:6: error: conflicting types for ‘ext_print_num’
     void ext_print_num(void* p0, GoInt64 p1)
          ^~~~~~~~~~~~~
    In file included from _cgo_export.c:4:0:
    wasmer.go:9:14: note: previous declaration of ‘ext_print_num’ was here
    FAIL	github.com/ChainSafe/gossamer/runtime [build failed]
    

    Additional context

    Also, just wondering if you have a gitter or some other channel I can reach you on. Thanks :)

    🐞 bug 📦 component-extension 
    opened by noot 14
  • Make `GetLastError` threadsafe

    Make `GetLastError` threadsafe

    Summary

    If I am running multiple independent wasmer instances concurrently in separate goroutines, can those goroutines safely call wasmer.GetLastError() and trust that they will return the error relevant to their local instance?

    For example, say I have multiple goroutine's doing the following. Can errStr be relied on?

    func runWasm() {
        // load a Module from some wasm called mod
    ...
    
        i, _ := mod.Instantiate()
        v, err := i.Exports["run"]
        if err != nil {
            errStr, _ := wasmer.GetLastError()
            panic(errStr)
        }
        ...
    }
    
    🎉 enhancement 📦 component-extension 
    opened by AdamSLevy 13
  • load wasm that build with golang

    load wasm that build with golang

    Thanks for the bug report!

    Describe the bug

    when I build wasm with go and wasm.NewInstance from the wasm bin, error result with:

    Failed to compile the module.
    

    A clear and concise description of what the bug is.

    Steps to reproduce

    1. build wasm with go GOARCH=wasm GOOS=js go build -o wa.wasm wa.go cat wa.go:
    package main
    
    //export Sum
    func Sum(x, y int) int {
    	return x + y
    }
    
    func main() {
    }
    
    1. build go program go build main.go cat main.go:
    package main
    
    import (
    	"fmt"
    	wasm "github.com/wasmerio/go-ext-wasm/wasmer"
    )
    
    func main() {
    	bytes, err := wasm.ReadBytes("wa.wasm");
    	if err != nil{
    		fmt.Println(err);
    		return
    	}
    	inst, err := wasm.NewInstance(bytes);
    	if err != nil{
    		fmt.Println(err);
    		return
    	}
    	defer inst.Close();
    
    	sum := inst.Exports["sum"]
    
    	result, err := sum(5,37);
    	if err != nil{
    		fmt.Println(err);
    		return;
    	}
    	fmt.Println(result);
    }
    
    1. Run
    ./main
    
    1. See error Failed to compile the module.
    ❓ question 📦 component-runtime 
    opened by bonly 12
  • Wasmer 1.0.2 function memory leak

    Wasmer 1.0.2 function memory leak

    Describe the bug

    Memory usage slowly builds up when calling wasm module functions causing our containers to go OOM.

    Steps to reproduce

    I've updated the demo repository at https://github.com/Polygens/wasmer-leak to reproduce the problem with wasmer 1.0. More info in the readme.

    Expected behavior

    After every iteration of the for loop in the demo repo I would expect memory usage to remain consistent. If we run the demo with a single iteration it uses around 28MB. Or at least garbage collected before going OOM.

    Actual behavior

    Instead of memory being released after every iteration it builds up and gets OOM killed. image

    Additional context

    We just upgraded to 1.0 to make use of the new traps :heart: but now we have an issue with the wasm functions taking too much memory. Not sure if this was present before 1.0, we had a similar issue with wasm instantiation but that seems unrelated.

    🐞 bug 
    opened by Polygens 11
  • Actually use WASM generated from Go code

    Actually use WASM generated from Go code

    Summary

    How to import and use WASM that was generated from Go code?

    Additional details

    Given that the examples in the README are somewhat a bit more convoluted, with some rust bits in between, I am still unsure whether this library is supposed to enable the use of WASM code that was actually generated from (pure) Go.

    For example, if I have:

    package main
    
    import "fmt"
    
    func Hello() {
    	fmt.Println("Hello, WebAssembly!")
    }
    
    func main() {
    	fmt.Println("Hello, WebAssembly!")
    }
    

    that I build as:

    GOOS=js GOARCH=wasm go build -o ./hello.wasm

    and that I want to use it in another program, such as:

    package main
    
    import (
    	"log"
    
    	"github.com/wasmerio/go-ext-wasm/wasmer"
    )
    
    func main() {
    	// Reads the WebAssembly module as bytes.
    	bytes, err := wasmer.ReadBytes("./hello.wasm")
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	// Instantiates the WebAssembly module.
    	instance, err := wasmer.NewInstance(bytes)
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer instance.Close()
    
    	hello := instance.Exports["Hello"]
    	hello()
    }
    

    then I get:

    go run ./main.go
    2020/04/08 14:14:32 Failed to instantiate the module:
        21 link errors: (1 of 21) Import not found, namespace: go, name: debug (2 of 21) Import not found, namespace: go, name: runtime.resetMemoryDataView (3 of 21) Import not found, namespace: go, name: runtime.wasmExit (4 of 21) Import not found, namespace: go, name: runtime.wasmWrite (5 of 21) Import not found, namespace: go, name: runtime.nanotime1 (6 of 21) Import not found, namespace: go, name: runtime.walltime1 (7 of 21) Import not found, namespace: go, name: runtime.scheduleTimeoutEvent (8 of 21) Import not found, namespace: go, name: runtime.clearTimeoutEvent (9 of 21) Import not found, namespace: go, name: runtime.getRandomData (10 of 21) Import not found, namespace: go, name: syscall/js.finalizeRef (11 of 21) Import not found, namespace: go, name: syscall/js.stringVal (12 of 21) Import not found, namespace: go, name: syscall/js.valueGet (13 of 21) Import not found, namespace: go, name: syscall/js.valueSet (14 of 21) Import not found, namespace: go, name: syscall/js.valueIndex (15 of 21) Import not found, namespace: go, name: syscall/js.valueSetIndex (16 of 21) Import not found, namespace: go, name: syscall/js.valueCall (17 of 21) Import not found, namespace: go, name: syscall/js.valueNew (18 of 21) Import not found, namespace: go, name: syscall/js.valueLength (19 of 21) Import not found, namespace: go, name: syscall/js.valuePrepareString (20 of 21) Import not found, namespace: go, name: syscall/js.valueLoadString (21 of 21) Import not found, namespace: go, name: syscall/js.copyBytesToJS
    exit status 1
    

    Is this expected? If yes, is there a way to achieve what I'm trying to do? From what I gathered in the official documentation (https://github.com/golang/go/wiki/WebAssembly) it seemed to me that WASM code that was generated from Go needed a javascript environment to run so I wouldn't expect go-ext-wasm to be able to handle it without embedding Node.js or something like that, but maybe I misunderstood?

    ❓ question 
    opened by mpl 11
  • Is go-wasmer can handle C codes?

    Is go-wasmer can handle C codes?

    Using go-wasmer we were able to handle Rust code by calling extern function.

    can we do same for C codes? is it compatible now?

    If yes. How can we call C code as an extern function?

    ❓ question 
    opened by AchalaSB 11
  • How can I have []byte array in a struct that is passed as my Context

    How can I have []byte array in a struct that is passed as my Context

    Summary

    I need to pass some byte[] array in addition to a few other values as my Context data. The unsafe Pointer thing with CGO seems to limit passing pointers with things other that value types.

    Do you know of a workaround to allow passing more complex context object around.

    ❓ question 
    opened by fproulx-dfuse 11
  • example imported_function.wasm    could not determine kind of name for C.sum

    example imported_function.wasm could not determine kind of name for C.sum

    func sum(context unsafe.Pointer, x int32, y int32) int32 {
    	return x + y
    }
    
    func Test3()  {
    	bytes, err := wasm1.ReadBytes("/Users/andy/Downloads/imported_function.wasm")
    	if err != nil {
    		fmt.Println(err)
    	}
    	imports, err := wasm1.NewImports().Append("sum", sum, C.sum)
    	if err != nil {
    		fmt.Println(err)
    	}
    
    	instance, _ := wasm1.NewInstanceWithImports(bytes, imports)
    
    	// Close the WebAssembly instance later.
    	defer instance.Close()
    
    	// Gets the `add1` exported function from the WebAssembly instance.
    	add1 := instance.Exports["add1"]
    
    	// Calls that exported function.
    	// As a reminder: `add1` is defined as `fn add1(x: i32, y: i32) -> i32 { sum(x, y) + 1 }`
    	result, _ := add1(1, 2)
    
    	// Should output 4 (= 1 + 2 + 1).
    	fmt.Println(result)
    }
    

    could not determine kind of name for C.sum


    Edit from @Hywan: Markup.

    ❓ question 
    opened by tx991020 10
  • chore(deps): bump thiserror from 1.0.26 to 1.0.32

    chore(deps): bump thiserror from 1.0.26 to 1.0.32

    Bumps thiserror from 1.0.26 to 1.0.32.

    Release notes

    Sourced from thiserror's releases.

    1.0.32

    • Add keywords to crates.io metadata

    1.0.31

    • Improve diagnostic when there is an enum variant containing #[from] #[backtrace] Error, Backtrace (#163)

    1.0.30

    • Make #[source] attribute usable on a field of type Box<dyn Error + Send + Sync + UnwindSafe + 'static> (#155, thanks @​cosmicexplorer)

    1.0.29

    • Support error types containing generic type parameters (#148, #149, #150, #151)

      use thiserror::Error;
      

      #[derive(Error, Debug)] pub enum MyError<E, F, G> { #[error("thing {0} ({0:?})")] Variant(E), #[error("some error")] Delegate(#[source] SomeError<F>), #[error("err 0o{val:o}")] Octal { val: G }, }

      In the above example, thiserror would automatically generate the following pair of generic trait impls.

      impl<E, F, G> std::error::Error for MyError<E, F, G>
      where
          SomeError<F>: std::error::Error + 'static,
          Self: std::fmt::Debug + std::fmt::Display;
      

      impl<E, F, G> std::fmt::Display for MyError<E, F, G> where E: std::fmt::Debug + std::fmt::Display, G: std::fmt::Octal;

    1.0.28

    • Make ? work with error types that hold an optional source (#147)

    1.0.27

    • Support forwarding backtrace method to source's backtrace method (#137, #146, thanks @​astraw)
    Commits
    • 8cb98af Release 1.0.32
    • c1fb583 Disable nightly backtrace testing until converted to provider API
    • 8b23fbb Update keywords in crates.io metadata
    • c79f5c9 Sort package entries in Cargo.toml
    • 24db929 Update ui test suite to nightly-2022-07-10
    • f09771e Ignore manual_find clippy lint
    • b338fe6 Update ui test suite to nightly-2022-07-02
    • d2f761f Use dtolnay/rust-toolchain's miri toolchain
    • e82ff36 Update ui test suite to nightly-2022-06-26
    • 799b3d3 Use upstreamed docs.rs icon in docs.rs badge
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies rust 
    opened by dependabot[bot] 0
  • Does wasmer-go support simd instruction?

    Does wasmer-go support simd instruction?

    I use wasmer-go to run wasm program contains simd instruction, but failed.

    go program:

    `package main

    import ( "fmt" wasmer "github.com/wasmerio/wasmer-go/wasmer" "io/ioutil" )

    func test(){ wasmBytes, _ := ioutil.ReadFile("./test.wasm")

    engine := wasmer.NewEngine()
    store := wasmer.NewStore(engine)
    
    // Compiles the module
    fmt.Println("Compiling module...")
    module, err := wasmer.NewModule(store, wasmBytes)
    if err != nil {
    		fmt.Println("Failed to compile module:", err)
    	}
    
    // Instantiates the module
    importObject := wasmer.NewImportObject()
    fmt.Println("Instantiating module...")
    instance, err := wasmer.NewInstance(module, importObject)
    if err != nil {
    	panic(fmt.Sprintln("Failed to instantiate the module:", err))
    }
    
    // Gets the `sum` exported function from the WebAssembly instance.
    func1, err := instance.Exports.GetFunction("func1")
    if err != nil {
    		panic(fmt.Sprintln("Failed to get the `func1` function:", err))
    	}
    
    fmt.Println("Calling `func1` function...")
    res, err := func1()
    
    if err != nil {
    		panic(fmt.Sprintln("Error caught from `func1`:", err))
    	}
    
    fmt.Println("Executing func1 res ...")
    fmt.Println(res)
    

    }

    func main(){ fmt.Println("========== Start test ==========") test() fmt.Println("========== Finish test ==========") }`

    The output is :

    compiling error

    ❓ question 
    opened by Zhangyx24 0
  • chore(deps): bump github.com/stretchr/testify from 1.7.0 to 1.8.0

    chore(deps): bump github.com/stretchr/testify from 1.7.0 to 1.8.0

    Bumps github.com/stretchr/testify from 1.7.0 to 1.8.0.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies go 
    opened by dependabot[bot] 0
  • What is the difference between wasmer-go and wasmer?

    What is the difference between wasmer-go and wasmer?

    I want to know What is the difference between wasmer-go and wasmer? What is the relationship between wasmer-go and wasmer?
    Does wasmer-go use part of code in wasmer?

    ❓ question 
    opened by Zhangyx24 0
  • Error handling from within guest when calling host function

    Error handling from within guest when calling host function

    Summary

    I've worked through the examples which illustrate how to deal with errors created by the guest function, but I need to deal with errors created by host functions. My host is Go and my guest is Rust. The host function looks like this

    fn := wasmer.NewFunction(store, wasmer.NewFunctionType(wasmer.NewValueTypes(), wasmer.NewValueTypes()),
    	func(values []wasmer.Value) ([]wasmer.Value, error) {
    		return nil, fmt.Errorf("error in the host function")
    	})
    importObject.Register("env", map[string]wasmer.IntoExtern{
    	"failable_function": fn,
    })
    

    And in my guest I'm doing this

    extern "C" {
        pub fn failable_function();
    }
    
    #[no_mangle]
    pub extern fn this_will_fail() {
        // ...even though I don't have an opportunity to deal with the error
        unsafe{failable_function()}
    
        // this doesn't work either because apparently its not a panic
        let _ = std::panic::catch_unwind(||{
            unsafe{failable_function()}
        });
    }
    

    The problem is that when I call the guest'sthis_will_fail function from the host, which then calls the host's failable_function from the guest, there is no opportunity for the guest to handle the error, it just returns the error right back to the host. Ideally, I'd be able to get some kind of Result wrapper around the function.

    ❓ question 
    opened by clarkmcc 0
  • Set Stdin for WasiEnvironment

    Set Stdin for WasiEnvironment

    Is there a way to set the Stdin for a WasiEnvironment? Currently it seems that the only way to set Stdin is to inherrit from the host (https://pkg.go.dev/github.com/wasmerio/wasmer-go/wasmer#WasiStateBuilder.InheritStdin).

    It would be very convenient if one could set the standard input to an io.Reader.

    ❓ question 
    opened by dvob 0
Releases(v1.0.4)
  • v1.0.4(Aug 12, 2021)

    Added

    • #230 Test against the nightly version of Wasmer everyday at 2am.
    • #229 Showcase how to get Instance inside a host function.

    Changed

    • #276 Update the underlying runtime to Wasmer 2.0, which provides improved performances, and better stability.
    • #268 and #247 Update all Rust dependencies.

    Fixed

    • #277 Force finalizers to explore the graph of objects.
    • #264 Update the store field when deserializing a Module.
    • #244 Place imports in Instance to prevent them being freed during function execution.
    • #242 Correctly handle I64 (and other) values returned from imported functions.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Feb 26, 2021)

    Added

    • #213 Add the CompilerKind, EngineKind, IsCompilerAvailable and IsEngineAvailable symbols.
    • #206 Use parameterized tests to check all available configurations.
    • #204 Add Config.UseSinglepassCompiler.
    • #193, #190 and #211 Add the custom_wasmer_runtime build tag.
    • #192 Add missing documentation.

    Changed

    (nothing)

    Fixed

    • #220 Test with more compilers and more engines.
    • #209 Fix documentation format.
    • #207 Avoid calling Function.Type() for every function call.
    • #198 Update shared libraries to fix a bug with CpuFeatures.Add.
    • #197 Force go mod vendor to copy the packaged/ directory.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Feb 26, 2021)

    Added

    • #190, #193 Add the custom_wasmer_runtime tag to use a specific Wasmer shared library object if the one you need is missing from the pre-compiled set.
    • #192 Improved the documentation by covering the entire API
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Feb 26, 2021)

  • v1.0.0(Feb 5, 2021)

    Added

    • Implement traps
    • Allow choosing an engine and a compiler through the configuration
    • Added support for aarch64
    • Implement WASI
    • Implement cross-compilation
    • Add support for host function environment

    Changed

    • Update to Wasmer 1.0.2
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0-beta2(Jan 5, 2021)

  • v1.0.0-beta1(Dec 3, 2020)

    Changed

    • The whole API changed to better match Wasmer and Wasm C API

      // Create an Engine
      engine := wasmer.NewEngine()
      
      // Create a Store
      store := wasmer.NewStore(engine)
      
      fmt.Println("Compiling module...")
      module, err := wasmer.NewModule(store, wasmBytes)
      
      if err != nil {	 
          fmt.Println("Failed to compile module:", err)
      }
      
      // Create an empty import object.
      importObject := wasmer.NewImportObject()
      
      fmt.Println("Instantiating module...")
      // Let's instantiate the Wasm module.
      instance, err := wasmer.NewInstance(module, importObject)
      
      if err != nil {	 
          panic(fmt.Sprintln("Failed to instantiate the module:", err))
      }
      

      Please refer to the examples and documentation to learn more about the changes.

    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Mar 3, 2020)

  • 0.3.0(Mar 2, 2020)

    Added

    • Memory can be imported, thus making the distinction between owned and borrowed memory (#119 by @koponen-styra).

      The main new methods are Imports.AppendMemory, and NewMemory to create a new memory with bounds (in pages).

      The Imports.Append method is now deprecated in favor of Imports.AppendFunction.

      // Compile a WebAssembly module
      module, _ := wasm.Compile(wasmBytes)
      
      // Create a new memory (that's new!)
      memory, _ := wasm.NewMemory(/* min page */ 1, /* max page */ 2)
      
      // Create an import object
      imports := wasm.NewImports().Namespace("env").AppendMemory("memory", memory)
      importObject := wasm.NewImportObject()
      _ = importObject.Extend(*imports)
      
      instance, _ := module.InstantiateWithImportObject(importObject)
      defer instance.Close()
      
      // Now we can read or write the memory with `memory.Data()` as usual
      
    • Add Bazel files to build the project with Bazel (#108 by @joesonw)

    • Support multiple WASI version with WasiGetVersion, NewDefaultWasiImportObjectForVersion, NewWasiImportObjectForVersion and WasiVersion (#92 by @Hywan).

      Supported version are:

      • Latest,
      • Snapshot0,
      • Snapshot1,
      • Unknown (in case of error).
      // Compile a WebAssembly module
      module, _ = wasm.Compile(wasmBytes)
      
      // Read the WASI version required for this module
      wasiVersion = wasm.WasiGetVersion(module)
      
      // Create an import object
      importObject := wasm.NewDefaultWasiImportObjectForVersion(wasiVersion)
      
      // Extend the import object with the imports
      imports, _ := wasm.NewImports().Namespace("env").AppendFunction("sum", sum, C.sum)
      _ = importObject.Extend(*imports)
      
      // Instantiate the module with the import object
      instante, _ := module.InstantiateWithImportObject(importObject)
      
    • InstanceContext supports user data with any reference types or types that include any reference types or other Go pointers (#85 and #94 by @AdamSLevy)

      type logMessageContext struct {
          message string
          slice []string // that wasn't possible before
          ptr *string    // that wasn't possible before
      }
      
      str := "test"
      contextData = logMessageContext {
          message: "first",
          slice:   []string{str, str},
          ptr:     &str,
      }
      
      instance.SetContextData(&contextData)
      
    • WASI is now supported (#72 by @MarkMcCaskey)

      // Compile a WebAssembly module
      module, _ = wasm.Compile(wasmBytes)
      
      // Declare imports as usual
      imports, _ := wasm.NewImports().Namespace("env").AppendFunction("sum", sum, C.sum)
      
      // Create an import object
      importObject := wasm.NewDefaultWasiImportObject()
      
      // Extend the import object with the imports
      _ = importObject.Extend(*imports)
      
      // Instantiate the module with the import object
      instance, _ = wasm.InstantiateWithImportObject(importObject)
      defer instance.Close()
      
      // Run the module
      instance.Exports["_start"]()
      
    • Instance supports optional memory, i.e. a WebAssembly module that does not have an exported memory, and provides a new HasMemory method (#63 by @Hywan)

    Changed

    • Remove unnecessary heap allocations and calls to C (#118 by @koponen-styra)
    • Update the cli package version to v2 (#110 by @d0iasm)
    • Migrate from CircleCI to Github Actions (#99 and #103 by @Hywan)
    • Explain how this package works (#97 by [@Hywan])
    • Make tests more portable by changing int64_t to long long in cgo (#67 by @ethanfrey)
    • Update build instructions (#66 by @ethanfrey)
    • Update Wasmer to 0.6.0 to 0.14.0 (#57, #64, #73, #80, #89, #107, #111 and #120 by @Hywan)

    Fixed

    • Fix build for go1.14beta1 on macOS (#114 by @chai2010)
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jul 16, 2019)

    Features

    • #55 Add the Memory.Grow method (@Hywan)

    • #42 Improve error messages when instantiating (@Hywan)

    • #38 Support import descriptors (@Hywan)

      var module, _ = wasm.Compile(bytes)
      
      assert.Equal(…, "log_message", module.Imports[0].Name)
      assert.Equal(…, "env", module.Imports[0].Namespace)
      
    • #37 Support export descriptors (@Hywan)

      var module, _ = wasm.Compile(bytes)
      
      assert.Equal(…, "sum", module.Exports[7].Name)
      
    • #34 Support module serialization and deserialization (@Hywan)

      // Compiles the bytes into a WebAssembly module.
      module1, _ := wasm.Compile(GetBytes())
      defer module1.Close()
      
      // Serializes the module into a sequence of bytes.
      serialization, _ := module1.Serialize()
      
      // Do something with `serialization`.
      // Then later…
      
      // Deserializes the module.
      module2, _ := wasm.DeserializeModule(serialization)
      defer module2.Close()
      // And enjoy!
      
      // Instantiates the WebAssembly module.
      instance, _ := module2.Instantiate()
      defer instance.Close()
      
      // Gets an exported function.
      sum, functionExists := instance.Exports["sum"]
      
      fmt.Println(functionExists)
      
      // Calls the `sum` exported function with Go values.
      result, _ := sum(1, 2)
      
      fmt.Println(result)
      
      // Output:
      // true
      // 3
      
    • #33 Add Compile, Module.Instantiate* and Module.Close (@Hywan)

    • #30 Support instance context data (@Hywan)

      //export logMessageWithContextData
      func logMessageWithContextData(context unsafe.Pointer, pointer int32, length int32) {
              var instanceContext = wasm.IntoInstanceContext(context)
              var memory = instanceContext.Memory().Data()
              var logMessage = (*logMessageContext)(instanceContext.Data())
      
              logMessage.message = string(memory[pointer : pointer+length])
      }
      
      type logMessageContext struct {
              message string
      }
      
      func testImportInstanceContextData(t *testing.T) {
              imports, err := wasm.NewImports().Append("log_message", logMessageWithContextData, C.logMessageWithContextData)
              assert.NoError(t, err)
      
              instance, err := wasm.NewInstanceWithImports(getImportedFunctionBytes("log.wasm"), imports)
              assert.NoError(t, err)
      
              defer instance.Close()
      
              contextData := logMessageContext{message: "first"}
              instance.SetContextData(unsafe.Pointer(&contextData))
      
              doSomething := instance.Exports["do_something"]
      
              result, err := doSomething()
      
              assert.NoError(t, err)
              assert.Equal(t, wasm.TypeVoid, result.GetType())
              assert.Equal(t, "hello", contextData.message)
      }
      
    • #29 Add Imports.Namespace to set the current import namespace (@Hywan)

      // By default, the namespace is `"env"`. Change it to `"ns"`.
      wasm.NewImports().Namespace("ns").Append("f", f, C.f)
      
    • #26 Support instance context API (@Hywan)

    Bug/security fixes

    • #56 Update Wasmer to 0.5.5 (@Hywan)

    Documentation/Test

    • #51 Test that all Wasm types can be used in imported functions (@Hywan)
    • #36 Improve the Benchmarks Section (@Hywan)
    • #32 Move examples in the root directory for godoc.org (@Hywan)
    • #31 Fix example namespaces for godoc.org (@Hywan)
    • #30 Increase the cgocheck level (@Hywan)

    Chore

    • #54 Reorganize bridge.go (@Hywan)
    • #15 Build and test on macOS (@Hywan)
    Source code(tar.gz)
    Source code(zip)
WebAssembly runtime for wasmer-go

gowasmer When compiling Go to WebAssembly, the Go compiler assumes the WebAssembly is going to run in a JavaScript environment. Hence a wasm_exec.js f

mattn 91 Jul 28, 2022
wazero: the zero dependency WebAssembly runtime for Go developers

wazero: the zero dependency WebAssembly runtime for Go developers WebAssembly is a way to safely run code compiled in other languages. Runtimes execut

Tetrate Labs 1.8k Aug 14, 2022
Go compiler for small places. Microcontrollers, WebAssembly, and command-line tools. Based on LLVM.

TinyGo - Go compiler for small places TinyGo is a Go compiler intended for use in small places such as microcontrollers, WebAssembly (Wasm), and comma

TinyGo 11.3k Aug 11, 2022
WebAssembly interop between Go and JS values.

vert Package vert provides WebAssembly interop between Go and JS values. Install GOOS=js GOARCH=wasm go get github.com/norunners/vert Examples Hello W

null 76 Aug 12, 2022
WebAssembly for Proxies (Golang host implementation)

WebAssembly for Proxies (GoLang host implementation) The GoLang implementation for proxy-wasm, enabling developer to run proxy-wasm extensions in Go.

MOSN 37 May 28, 2022
Golang-WASM provides a simple idiomatic, and comprehensive API and bindings for working with WebAssembly for Go and JavaScript developers

A bridge and bindings for JS DOM API with Go WebAssembly. Written by Team Ortix - Hamza Ali and Chan Wen Xu. GOOS=js GOARCH=wasm go get -u github.com/

TeamOrtix 74 Jul 15, 2022
A package to build progressive web apps with Go programming language and WebAssembly.

Go-app is a package for building progressive web apps (PWA) with the Go programming language (Golang) and WebAssembly (Wasm). Shaping a UI is done by

Maxence Charriere 6.4k Aug 14, 2022
A package to build progressive web apps with Go programming language and WebAssembly.

Go-app is a package for building progressive web apps (PWA) with the Go programming language (Golang) and WebAssembly (Wasm). Shaping a UI is done by

Maxence Charriere 6.4k Aug 8, 2022
Vugu: A modern UI library for Go+WebAssembly (experimental)

Vugu: A modern UI library for Go+WebAssembly (experimental)

Vugu 4.5k Aug 16, 2022
A template project to demonstrate how to run WebAssembly functions as sidecar microservices in dapr

Live Demo 1. Introduction DAPR is a portable, event-driven runtime that makes it easy for any developer to build resilient, stateless and stateful app

Second State 129 Aug 12, 2022
Tiny, blazing fast WebAssembly compute

Sat, the tiny WebAssembly compute module Sat (as in satellite) is an experiment, and isn't ready for production use. Please try it out and give feedba

Suborbital 289 Aug 7, 2022
WebAssembly Lightweight Javascript Framework in Go (AngularJS Inspired)

Tango Lightweight WASM HTML / Javascript Framework Intro WebAssembly is nice, Go on the web is nice, so I ported Tangu to Go and WebAssembly. Tangu is

enimatek 4 Jun 8, 2022
Running a Command line tool written in Go on browser with WebAssembly

Running a command line tool written in Go on browser with WebAssembly This repo contains code/assets from the article Files: . ├── article.md

wcchoi 79 Jul 3, 2022
This library provides WebAssembly capability for goja Javascript engine

This module provides WebAssembly functions into goja javascript engine.

YC-L 1 Jan 10, 2022
A Brainfuck to WebAssembly compiler written in Go.

brainfuck2wasm A Brainfuck to WebAssembly compiler written in Go. I am writing this compiler for a Medium article. When I complete the compiler, I'll

Luke I. Wilson 2 Jun 6, 2022
Dom - A Go API for different Web APIs for WebAssembly target

Go DOM binding (and more) for WebAssembly This library provides a Go API for dif

Denys Smirnov 460 Aug 4, 2022
🐹🕸️ WebAssembly runtime for Go

Wasmer Go Website • Docs • Slack Channel A complete and mature WebAssembly runtime for Go based on Wasmer. Features Easy to use: The wasmer API mimics

Wasmer 2.1k Aug 12, 2022
WebAssembly runtime for wasmer-go

gowasmer When compiling Go to WebAssembly, the Go compiler assumes the WebAssembly is going to run in a JavaScript environment. Hence a wasm_exec.js f

mattn 91 Jul 28, 2022
wazero: the zero dependency WebAssembly runtime for Go developers

wazero: the zero dependency WebAssembly runtime for Go developers WebAssembly is a way to safely run code compiled in other languages. Runtimes execut

Tetrate Labs 1.8k Aug 14, 2022
Identify containers at runtime and observe them. No container runtime required. Read only access to the kernel.

Linux Telemetry The Double Slit Experiment Taken from an interesting physics anomaly where the behavior of a physical system mutates simply by being o

Kris Nóva 13 Mar 30, 2022
golang-runtime-di is a framework for runtime dependency injection in go

golang-runtime-di description golang-runtime-di is a framework for runtime dependency injection in go. usage quickstart add it to your go.mod: go get

DB Systel GmbH 2 Aug 1, 2022
A package to build progressive web apps with Go programming language and WebAssembly.

go-app is a package to build progressive web apps (PWA) with Go programming language and WebAssembly. It uses a declarative syntax that allows creatin

Maxence Charriere 6.4k Aug 10, 2022
Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly

Introduction Qt is a free and open-source widget toolkit for creating graphical user interfaces as well as cross-platform applications that run on var

null 9.4k Aug 8, 2022
Go compiler for small places. Microcontrollers, WebAssembly, and command-line tools. Based on LLVM.

TinyGo - Go compiler for small places TinyGo is a Go compiler intended for use in small places such as microcontrollers, WebAssembly (Wasm), and comma

TinyGo 11.3k Aug 11, 2022
WebAssembly interop between Go and JS values.

vert Package vert provides WebAssembly interop between Go and JS values. Install GOOS=js GOARCH=wasm go get github.com/norunners/vert Examples Hello W

null 76 Aug 12, 2022
WebAssembly for Proxies (Golang host implementation)

WebAssembly for Proxies (GoLang host implementation) The GoLang implementation for proxy-wasm, enabling developer to run proxy-wasm extensions in Go.

MOSN 37 May 28, 2022
Go compiler for small places. Microcontrollers, WebAssembly, and command-line tools. Based on LLVM.

TinyGo - Go compiler for small places TinyGo is a Go compiler intended for use in small places such as microcontrollers, WebAssembly (Wasm), and comma

TinyGo 11.3k Aug 10, 2022
wagon, a WebAssembly-based Go interpreter, for Go.

wagon wagon is a WebAssembly-based interpreter in Go, for Go. As of 2020/05/11 Wagon is in read-only mode, and looking for a maintainer. You may want

Go Interpreter 900 Aug 6, 2022
Golang-WASM provides a simple idiomatic, and comprehensive API and bindings for working with WebAssembly for Go and JavaScript developers

A bridge and bindings for JS DOM API with Go WebAssembly. Written by Team Ortix - Hamza Ali and Chan Wen Xu. GOOS=js GOARCH=wasm go get -u github.com/

TeamOrtix 74 Jul 15, 2022