Git Product home page Git Product logo

hammertime's Introduction

πŸ”¨ hammertime GoDoc

import "github.com/guregu/hammertime"

Do you want to use the excellent wasmtime-go Wasm runtime library, but are missing some features like capturing stdout or setting stdin?

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 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

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.

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:

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 embed

func 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, then do something like:

$ export WASI_CC=/path/to/wasi-sdk-XX.0/bin/clang
$ make -j8

hammertime's People

Contributors

guregu avatar

Stargazers

kyong avatar Chris avatar Yota Hamada avatar Eric Dykstra avatar Matt Mueller avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.