🐹🕸️ 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.

Comments
  • 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
  • How do I enable threads for my module?

    How do I enable threads for my module?

    Summary

    I enabled threads and shared memory for my AssemblyScript module and it compiles fine, but when I try to use it in wasmer it says threads must be enabled. I can't seem to find any options for this. Am I missing something or is this a bug?

    Additional details

    My error: 2023/01/03 17:26:13 failed to create WASM module: Validation error: threads must be enabled for shared memories (at offset 112) exit status 1

    ❓ question 
    opened by alexpitsikoulis 0
  • Build fails due to missing -lwasmer library when vendored

    Build fails due to missing -lwasmer library when vendored

    Describe The Bug

    The library works fine unless I vendor, in which case the build fails

    Steps To Reproduce

    1. Create project using the library
    2. go mod vendor
    3. build the project

    Expected Behavior

    Successful build

    Actual Behavior

    /usr/local/go/pkg/tool/darwin_arm64/link: running clang failed: exit status 1 ld: warning: directory not found for option '-L/<PATH TO DIRECTORY>/vendor/github.com/wasmerio/wasmer-go/wasmer/packaged/lib/darwin-aarch64' ld: library not found for -lwasmer clang: error: linker command failed with exit code 1 (use -v to see invocation)

    opened by alexpitsikoulis 0
  • chore(deps): bump thiserror from 1.0.26 to 1.0.38

    chore(deps): bump thiserror from 1.0.26 to 1.0.38

    Bumps thiserror from 1.0.26 to 1.0.38.

    Release notes

    Sourced from thiserror's releases.

    1.0.38

    • Documentation improvements

    1.0.37

    • Documentation improvements

    1.0.36

    1.0.35

    • More work on integrating std::any::Provider for backtrace support
    • Fix "Multiple applicable provide methods in scope" error when the caller has both std::error::Error and std::any::Provide traits in scope (#185)

    1.0.34

    • Tweak "generic member access" based Backtrace implementation (#184)

    1.0.33

    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
      

    ... (truncated)

    Commits
    • 74bfe75 Release 1.0.38
    • cfc7d8c Update build status badge
    • db78fa2 Update ui test suite to nightly-2022-12-15
    • c25a710 Time out workflows after 45 minutes
    • 464e2e7 Merge pull request #200 from dtolnay/displayattr
    • 4b06a3e Add test of Display impl nested inside display attribute
    • 29ee95e Ui test changes for trybuild 1.0.66
    • 8a996a5 Release 1.0.37
    • 3a0bac2 Merge pull request #197 from dtolnay/backtracedoc
    • c2759ce Fix documentation mentioning 'backtrace()' method
    • 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
  • NewInstance() function returning nil as primary value and an error.

    NewInstance() function returning nil as primary value and an error.

    Thanks for the bug report!

    Describe the bug

    I have written a simple Go module with a simple function and generated a .wasm file via the Go compiler. While loading the same .wasm file in another Go module, the NewInstance() function returns an error:

    Missing import: `go`.`debug`
    

    Expected behavior

    The NewInstance() function should return a value of type *wasmer.Instance and nil as error.

    Actual behavior

    The NewInstance function returns nil as the primary value instead of *wasmer.Instance variable. And the error is returned to be:

    Missing import: `go`.`debug`
    

    The exact line is:

    instance, err := wasmer.NewInstance(module, importObject)
    
    🐞 bug 
    opened by KILLinefficiency 0
  • How to stop a running wasm function call?

    How to stop a running wasm function call?

    Thanks for the bug report!

    Describe the bug

    I start a go routine, the go routine call the wasm function, then i stop the wasm instance, then it panic.

    Steps to reproduce

    1. Build a wasm binary by the code
    EMSCRIPTEN_KEEPALIVE char* loop(int i) {
        while(true) {
            printf("%d\n", i);
        }
        return NULL;
    }
    
    1. load the wasm binary and get the NativeFunction loop
    go func() {
    		_, err := loop(int32(i))
    		fmt.Printf("err=%v\n", err)
    	}()
    	time.Sleep(time.Second * 1)
    	wasmStruct.instance.Close()
    
    1. run the code
    2. See error
    fatal error: unexpected signal during runtime execution
    [signal SIGSEGV: segmentation violation code=0x2 addr=0x298514c2c pc=0x101720a30]
    
    runtime stack:
    runtime.throw({0x1004da2e0?, 0x298000000?})
            /go1.18.4/src/runtime/panic.go:992 +0x50
    runtime.sigpanic()
            /go1.18.4/src/runtime/signal_unix.go:802 +0x1e8
    
    goroutine 34 [syscall]:
    runtime.cgocall(0x1004ce1a4, 0x14000418548)
            /go1.18.4/src/runtime/cgocall.go:157 +0x54 fp=0x14000418510 sp=0x140004184d0 pc=0x10034ff94
    github.com/wasmerio/wasmer-go/wasmer._Cfunc_wasm_func_call(0x6000003ccdc0, 0x14000012530, 0x14000012520)
            _cgo_gotypes.go:1235 +0x3c fp=0x14000418540 sp=0x14000418510 pc=0x1004176dc
    github.com/wasmerio/wasmer-go/wasmer.(*Function).Native.func1.5(0x14000012530?, 0x0?, 0x1400001e150?)
            /pkg/mod/github.com/wasmerio/[email protected]/wasmer/function.go:317 +0xcc fp=0x14000418590 sp=0x14000418540 pc=0x10041d6cc
    github.com/wasmerio/wasmer-go/wasmer.(*Function).Native.func1({0x14000012510, 0x1, 0x1004d1041?})
            /pkg/mod/github.com/wasmerio/[email protected]/wasmer/function.go:317 +0x2e8 fp=0x14000418740 sp=0x14000418590 pc=0x10041d1e8
    script_myself/wasmer.ExecuteLoop.func1()
           loop.go:21 +0xb4 fp=0x140004187d0 sp=0x14000418740 pc=0x1004cd674
    runtime.goexit()
            /go1.18.4/src/runtime/asm_arm64.s:1263 +0x4 fp=0x140004187d0 sp=0x140004187d0 pc=0x1003ac844
    created by script_myself/wasmer.ExecuteLoop
            loop.go:20 +0x70
    
    goroutine 1 [sleep]:
    time.Sleep(0x12a05f200)
            /go1.18.4/src/runtime/time.go:194 +0x11c
    
    exit status 2
    
    

    Expected behavior

    the NativeFunction loop stop print.

    Actual behavior

    panic

    🐞 bug 
    opened by Celebraty 0
  • GetFunction Missing 4 argument(s) when calling the function

    GetFunction Missing 4 argument(s) when calling the function

    Summary

    happen error

    GetFunction Missing 4 argument(s) when calling the function; Expected 5 argument(s), received 1
    

    Additional details

    I use the code to build wasm by tinygo.

    package main
    
    func main() {
    }
    
    //go:export add
    func Add(a, b int) int {
    	return a + b
    }
    
    //go:export replace
    func Replace(a string) string {
    	return a + "..."
    }
    

    go code

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    
    	wasmer "github.com/wasmerio/wasmer-go/wasmer"
    )
    
    func main() {
    	wasmBytes, _ := ioutil.ReadFile("module.wasm")
    
    	engine := wasmer.NewEngine()
    	store := wasmer.NewStore(engine)
    
    	// Compiles the module
    	module, err := wasmer.NewModule(store, wasmBytes)
    	if err != nil {
    		panic(err)
    	}
    
    	wasiEnv, _ := wasmer.NewWasiStateBuilder("wasi-program").CaptureStdout().CaptureStderr().Finalize()
    
    	importObject, err := wasiEnv.GenerateImportObject(store, module)
    	if err != nil {
    		panic(err)
    	}
    	instance, err := wasmer.NewInstance(module, importObject)
    	if err != nil {
    		panic(err)
    	}
    
    	addfunc, _ := instance.Exports.GetFunction("add")
    	result, _ := addfunc(1, 3)
    	fmt.Println(result)
    
    	replace, _ := instance.Exports.GetFunction("replace")
    	result, err = replace("aaa")
    	fmt.Println(result, err)
    }
    

    the function add run successfully, but function replace failed to run.

    4
    <nil> Missing 4 argument(s) when calling the function; Expected 5 argument(s), received 1
    
    ❓ question 
    opened by rfyiamcool 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)
Owner
Wasmer
Wasmer ❤️ Open Source
Wasmer
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 99 Dec 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 2.3k Jan 2, 2023
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 12.1k Dec 30, 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 83 Dec 28, 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 38 Dec 29, 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 93 Dec 22, 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.7k Dec 30, 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.7k Jan 2, 2023
Vugu: A modern UI library for Go+WebAssembly (experimental)

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

Vugu 4.5k Jan 3, 2023
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 185 Jan 3, 2023
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 320 Jan 5, 2023
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 8 Dec 20, 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 82 Dec 30, 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 472 Jan 7, 2023
🐹🕸️ 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.3k Dec 29, 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 99 Dec 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 2.3k Jan 2, 2023
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 14 Sep 18, 2022