# go-ext-wasm
**Repository Path**: liunix61/go-ext-wasm
## Basic Information
- **Project Name**: go-ext-wasm
- **Description**: Wasmer 是一个 Go 库,用来执行 WebAssembly 二进制程序
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 6
- **Created**: 2023-09-14
- **Last Updated**: 2023-09-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
A complete and mature WebAssembly runtime for Go based on
[Wasmer](https://github.com/wasmerio/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](https://pkg.go.dev/github.com/wasmerio/wasmer-go/wasmer)
full of examples.
**Examples** as tutorials: [browse the `examples/`
directory](https://github.com/wasmerio/wasmer-go/tree/master/examples),
it's the best place for a complete introduction!
# Install
To install the library, follow the classical:
```sh
$ 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`](https://golang.org/cmd/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](https://github.com/wasmerio/wasmer-go/issues/191).
Here are the steps to do that manually:
```sh
$ # 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/`](https://github.com/wasmerio/wasmer-go/tree/master/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:
```rust
#[no_mangle]
pub extern "C" fn sum(x: i32, y: i32) -> i32 {
x + y
}
```
A compiled WebAssembly binary is included in
[`examples/appendices/simple.wasm`]((https://github.com/wasmerio/wasmer-go/blob/master/examples/appendices/simple.wasm)).
Then, we can execute it in Go:
```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:
```sh
$ cd examples/appendices/
$ go run simple.go
42
```
# Testing
Run the tests with the following command:
```sh
$ just test
```
# What is WebAssembly?
Quoting [the WebAssembly site](https://webassembly.org/):
> 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](https://webassembly.org/docs/portability/#assumptions-for-efficient-execution)
> available on a wide range of platforms.
About safety:
> WebAssembly describes a memory-safe, sandboxed [execution
> environment](https://webassembly.org/docs/semantics/#linear-memory) […].
# License
The entire project is under the MIT License. Please read [the
`LICENSE` file][license].
[license]: https://github.com/wasmerio/wasmer/blob/master/LICENSE
# FAQ
## How to run Go programs compiled to WebAssembly modules with `wasmer-go`?
Let's start by emphasing that `wasmer-go` is a WebAssembly runtime. It
allows to _run_ WebAssembly inside Go. It's not a tool to _compile_ a
Go program into WebAssembly. Nonetheless, many people are reporting
issues when compiling Go programs to WebAssembly, and then trying to
run them with `wasmer-go` (or in another hosts, like
[Python](https://github.com/wasmerio/wasmer-python),
[C](https://github.com/wasmerio/wasmer/tree/master/lib/c-api),
[PHP](https://github.com/wasmerio/wasmer-php),
[Ruby](https://github.com/wasmerio/wasmer-ruby),
[Rust](https://github.com/wasmerio/wasmer)…).
The major problem is that, whilst the Go compiler supports
WebAssembly, [it does not support
WASI](https://github.com/golang/go/issues/31105) (WebAssembly System
Interface). It generates an ABI that is deeply tied to JavaScript, and
one needs to use the `wasm_exec.js` file provided by the Go toolchain,
which doesn't work outside a JavaScript host.
Fortunately, there are two solutions to this problem:
1. Use [TinyGo](https://tinygo.org) to compile your Go program to
WebAssembly with the `-target wasi` option, e.g.:
```sh
$ tinygo build -o module.wasm -target wasi .
```
The generated WebAssembly module will be portable across all
WebAssembly runtimes that support WASI.
2. Use the Go compiler with adapters. Let's see how to compile:
```sh
$ GOOS=js GOARCH=wasm go build -o module.wasm .
```
(the `GOOS=js` is the sign that JavaScript is targeted, not a surprise).
Then pick one adapter (they are written by the community):
* [`mattn/gowasmer`](https://github.com/mattn/gowasmer/),
* [`go-wasm-adapter/go-wasm`](https://github.com/go-wasm-adapter/go-wasm/),
and follow their documentation.
We highly recommend the first solution (with TinyGo) if it works for
you as the WebAssembly module will be portable across all WebAssembly
runtimes. It's not a hacky solution based on adapters; it's the right
way to… go.