Skip to content

Commit

Permalink
Wasm (#737)
Browse files Browse the repository at this point in the history
* wasm
  • Loading branch information
batmac authored Sep 18, 2024
1 parent 02cc00c commit 730e14f
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 0 deletions.
41 changes: 41 additions & 0 deletions example/plugins/wasm/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

// zig cc --target=wasm32-wasi main.c -o c.wasm

int main(int argc, char **argv)
{
ssize_t n, m;
char buf[BUFSIZ];

int in = STDIN_FILENO;
int out = STDOUT_FILENO;

while ((n = read(in, buf, BUFSIZ)) > 0)
{
char *ptr = buf;
while (n > 0)
{
m = write(out, ptr, (size_t)n);
if (m < 0)
{
fprintf(stderr, "write error: %s\n", strerror(errno));
exit(1);
}
n -= m;
ptr += m;
}
}

if (n < 0)
{
fprintf(stderr, "read error: %s\n", strerror(errno));
exit(1);
}

return EXIT_SUCCESS;
}
27 changes: 27 additions & 0 deletions example/plugins/wasm/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build ignore

// compile with:
// GOOS=wasip1 GOARCH=wasm go build -o go.wasm go.go
// or
// tinygo build -o tgo.wasm -target=wasi -scheduler=none -no-debug main.go

package main

import (
"bufio"
"os"
)

func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)

for {
input, err := reader.ReadString('\n')
writer.WriteString(input)
if err != nil {
break
}
}
writer.Flush()
}
10 changes: 10 additions & 0 deletions example/plugins/wasm/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//rustc main.rs --target wasm32-wasip1 -o rust.wasm

use std::io::{self, Read, Write};

fn main() {
let mut buffer = Vec::new();
let _ = io::stdin().read_to_end(&mut buffer);
let _ = io::stdout().write_all(&buffer);
()
}
17 changes: 17 additions & 0 deletions example/plugins/wasm/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// zig cc --target=wasm32-wasi main.zig -o zig.wasm
const std = @import("std");

pub fn main() !void {
var stdin = std.io.getStdIn().reader();
var stdout = std.io.getStdOut().writer();

const bufferSize: usize = 4096;
var buffer: [bufferSize]u8 = undefined;

while (true) {
const bytesRead = try stdin.read(buffer[0..]);
if (bytesRead == 0) break;

_ = try stdout.write(buffer[0..bytesRead]);
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/robert-nix/ansihtml v1.0.1
github.com/sashabaranov/go-openai v1.29.2
github.com/spf13/pflag v1.0.5
github.com/tetratelabs/wazero v1.8.0
github.com/titanous/json5 v1.0.0
github.com/tmc/keyring v0.0.0-20230418032330-0c8bdba76fa8
github.com/traefik/yaegi v0.16.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g=
github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
github.com/titanous/json5 v1.0.0 h1:hJf8Su1d9NuI/ffpxgxQfxh/UiBFZX7bMPid0rIL/7s=
github.com/titanous/json5 v1.0.0/go.mod h1:7JH1M8/LHKc6cyP5o5g3CSaRj+mBrIimTxzpvmckH8c=
github.com/tmc/keyring v0.0.0-20230418032330-0c8bdba76fa8 h1:DljNLO6GK8JXxL2VTe3dSGhraDappqRW7yrGvsW4U7w=
Expand Down
62 changes: 62 additions & 0 deletions pkg/mutators/single/wazero.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package mutators

import (
"context"
"errors"
"fmt"
"io"
"os"

"github.com/batmac/ccat/pkg/log"

"github.com/tetratelabs/wazero"
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
"github.com/tetratelabs/wazero/sys"
// "github.com/tetratelabs/wazero/api"
)

// Yaegi is a mutator that executes a yaegi script

func init() {
singleRegister("wasm", wasm, withDescription("a wasi (wasm) module to apply (path as first argument"),
withConfigBuilder(stdConfigString),
withCategory("plugin"),
)
}

func wasm(w io.WriteCloser, r io.ReadCloser, arg any) (int64, error) {
ctx := context.Background()
moduleFile := arg.(string)

log.Debugln("Create a new WebAssembly runtime")
runtime := wazero.NewRuntime(ctx)
defer runtime.Close(ctx)

log.Debugln("Instantiate WASI in the runtime")
wasi_snapshot_preview1.MustInstantiate(ctx, runtime)

log.Debugln("Load your WASM module")
wasmBytes, err := os.ReadFile(moduleFile)
if err != nil {
panic(fmt.Sprintf("Failed to read WASM module: %v", err))
}

log.Debugln("Define the configuration with the in-memory file system")
config := wazero.NewModuleConfig().
WithStdin(r).
WithStdout(w).
WithStderr(os.Stderr) // Set stderr to the standard error of the host process

log.Debugln("Instantiate the WASM module with the configured input/output")
if _, err := runtime.InstantiateWithConfig(ctx, wasmBytes, config); err != nil {
var exitErr *sys.ExitError
if errors.As(err, &exitErr) && exitErr.ExitCode() != 0 {
log.Debugf("exit_code: %d\n", exitErr.ExitCode())
} else {
log.Fatal(err)
}
}
w.Close()

return 0, nil
}

0 comments on commit 730e14f

Please sign in to comment.