Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/guregu/hammertime
alternative WASI for wasmtime-go
https://github.com/guregu/hammertime
Last synced: 25 days ago
JSON representation
alternative WASI for wasmtime-go
- Host: GitHub
- URL: https://github.com/guregu/hammertime
- Owner: guregu
- License: bsd-2-clause
- Created: 2023-07-30T17:05:36.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-08-11T11:37:12.000Z (about 1 year ago)
- Last Synced: 2024-08-01T13:29:31.690Z (3 months ago)
- Language: Go
- Size: 82 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ccamel - guregu/hammertime - alternative WASI for wasmtime-go (Go)
README
# π¨ hammertime [![GoDoc](https://godoc.org/github.com/guregu/hammertime?status.svg)](https://godoc.org/github.com/guregu/hammertime)
`import "github.com/guregu/hammertime"`
Do you want to use the excellent [wasmtime-go](https://github.com/bytecodealliance/wasmtime-go) Wasm runtime library, but are missing some features like [capturing stdout or setting stdin](https://github.com/bytecodealliance/wasmtime-go/issues/34)?
This library is a WASI implementation in Go for wasmtime-go. Its goal is to integrate Wasm more deeply with Go but still take advantage of Wasmtime's speedy runtime.
#### Status
Rough proof of concept targeting `wasi_snapshot_preview1`. If this project proves to be useful, I'm thinking a code generation approach targeting preview2 would be the next step.
TL;DR: Alpha!
- βοΈ Note that hammertime does not implement the preview1 capabilities model (yet?).
- β£οΈ It's also not safe to share WASI instances concurrently or across instances (yet?).
- π Lots of `unsafe`. Needs fuzzing or something.
- π€ Experimental. Ideas welcome!## Features
- Uses `fs.FS` for the Wasm filesystem. Supports [`hackpadfs`](https://github.com/hack-pad/hackpadfs#file-systems) extensions to add writing, etc.
- `stdin` can be set to an `io.Reader`.
- `stdout` and `stderr` can be set to a `io.Writer`.
- More experimental stuff coming soon?| WASI API | Vibe |
|---------------------------|--------|
| args_sizes_get | π |
| args_get | π |
| environ_sizes_get | π |
| environ_get | π |
| clock_time_get | π§ |
| fd_close | π§ |
| fd_fdstat_get | π |
| fd_fdstat_set_flags | πΆβπ«οΈ |
| fd_prestat_get | π |
| fd_prestat_dir_name | π |
| fd_filestat_get | π§ |
| fd_seek | π |
| fd_write | π |
| fd_read | π |
| fd_pread | π§ |
| fd_readdir | π |
| path_open | π§ |
| path_filestat_get | π§ |
| path_readlink | π§ |
| path_rename | π§ |
| path_create_directory | π |
| path_remove_directory | π |
| path_unlink_file | π |
| poll_oneoff | πΆβπ«οΈ |
| proc_exit | πΆβπ«οΈ |#### Legend
| | Interpretation |
| -- | ------------------------------ |
| π | Pretty good |
| π | Not bad |
| π§ | Needs more work/testing/love |
| πΆβπ«οΈ | Stub/missing |# Usage
See: [Godoc](https://godoc.org/github.com/guregu/hammertime)
### Quick Start
Imagine we have this C program we want to execute as WebAssembly. It's a simple program that receives a newline-separated list of who to greet via standard input, and writes "hello {name}" to standard output.
```c
int main() {
char *line = NULL;
size_t len = 0;
ssize_t read = 0;
while ((read = getline(&line, &len, stdin)) != -1) {
printf("hello %s", line);
}
free(line);
return 0;
}
```We can embed and execute it in a Go program like so, capturing the output:
```go
import (
"bytes"
_ "embed"
"log"
"os""github.com/bytecodealliance/wasmtime-go/v11"
"github.com/guregu/hammertime"
)//go:embed hello.wasm
var wasmModule []byte // Protip: stuff your modules into your binary with embedfunc main() {
// Standard boilerplate
engine := wasmtime.NewEngine()
store := wasmtime.NewStore(engine)
module, err := wasmtime.NewModule(engine, wasmModule)
if err != nil {
panic(err)
}
linker := wasmtime.NewLinker(engine)// Prepare our input and output
input := "alice\nbob\n"
stdin := strings.NewReader(input)
stdout := new(bytes.Buffer)// Set up our custom WASI
wasi := hammertime.NewWASI(
WithArgs([]string{"hello.wasm"}),
WithStdin(stdin), // Stdin can be any io.Reader
WithStdout(stdout), // Capture stdout to a *bytes.Buffer!
WithFS(os.DirFS("testdata")), // Works with Go's fs.FS! (kind of)
)
// Link our WASI
if err := wasi.Link(store, linker); err != nil {
panic(err)
}// Use wasmtime as normal
instance, err := linker.Instantiate(store, module)
if err != nil {
panic(err)
}
start := instance.GetFunc(store, "_start")
_, err = start.Call(store)
if err != nil {
panic(err)
}// Grab captured stdout data
output := stdout.String()
fmt.Println(output)
// Prints: hello alice
// hello bob
}
```This gives us an easy way to communicate with wasm modules.
# Testing
Each testdata/*.c file is a little self-contained C program that tests a WASI feature.
To build/run the test files, [install WASI SDK](https://github.com/WebAssembly/wasi-sdk#install), then do something like:
```console
$ export WASI_CC=/path/to/wasi-sdk-XX.0/bin/clang
$ make -j8
```