Skip to content

Commit

Permalink
lib: add support for wasi and compressed objects
Browse files Browse the repository at this point in the history
  • Loading branch information
efd6 committed Dec 20, 2023
1 parent ef16c8d commit 8c2e50c
Show file tree
Hide file tree
Showing 4 changed files with 710 additions and 17 deletions.
69 changes: 63 additions & 6 deletions lib/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package lib

import (
"bytes"
"compress/bzip2"
"compress/gzip"
"errors"
"fmt"
"io"
Expand All @@ -32,9 +34,17 @@ import (
"github.com/wasmerio/wasmer-go/wasmer"
)

type WASMEnvironment int

const (
UnknownWASMEnvironment WASMEnvironment = iota + 1
WASIEnvironment
)

type WASMModule struct {
Object []byte
Funcs map[string]WASMDecl
Object []byte
Environment WASMEnvironment
Funcs map[string]WASMDecl
}

type WASMDecl struct {
Expand Down Expand Up @@ -70,7 +80,11 @@ func WASM(adapter ref.TypeAdapter, modules map[string]WASMModule) (cel.EnvOption
}
mods := make(map[string]wasmModule, len(modules))
for modName, mod := range modules {
inst, funcs, err := compile(mod.Object, mod.Funcs)
obj, err := expand(mod.Object)
if err != nil {
return nil, err
}
inst, funcs, err := compile(obj, mod.Funcs, mod.Environment)
if err != nil {
return nil, err
}
Expand All @@ -96,12 +110,55 @@ func WASM(adapter ref.TypeAdapter, modules map[string]WASMModule) (cel.EnvOption
return cel.Lib(wasmLib{adapter: adapter, modules: mods}), nil
}

func compile(obj []byte, decls map[string]WASMDecl) (*wasmer.Instance, map[string]wasmer.NativeFunction, error) {
module, err := wasmer.NewModule(wasmer.NewStore(wasmer.NewEngine()), obj)
func expand(obj []byte) ([]byte, error) {
var (
r io.Reader
err error
)
switch {
case bytes.HasPrefix(obj, []byte{0x00, 0x61, 0x73, 0x6d}):
return obj, nil
case bytes.HasPrefix(obj, []byte{0x1f, 0x8b}):
r, err = gzip.NewReader(bytes.NewReader(obj))
if err != nil {
return nil, fmt.Errorf("invalid object: %w", err)
}
case bytes.HasPrefix(obj, []byte{0x42, 0x5a, 0x68}):
r = bzip2.NewReader(bytes.NewReader(obj))
default:
return nil, errors.New("invalid object: unrecognized magic bytes")
}
var buf bytes.Buffer
_, err = io.Copy(&buf, r)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}

func compile(obj []byte, decls map[string]WASMDecl, env WASMEnvironment) (*wasmer.Instance, map[string]wasmer.NativeFunction, error) {
store := wasmer.NewStore(wasmer.NewEngine())
module, err := wasmer.NewModule(store, obj)
if err != nil {
return nil, nil, err
}
inst, err := wasmer.NewInstance(module, wasmer.NewImportObject())
var importObject *wasmer.ImportObject
switch env {
case UnknownWASMEnvironment:
importObject = wasmer.NewImportObject()
case WASIEnvironment:
wasi, err := wasmer.NewWasiStateBuilder("wasi-program").Finalize()
if err != nil {
return nil, nil, err
}
importObject, err = wasi.GenerateImportObject(store, module)
if err != nil {
return nil, nil, err
}
default:
return nil, nil, fmt.Errorf("invalid environment: %v", env)
}
inst, err := wasmer.NewInstance(module, importObject)
if err != nil {
return nil, nil, err
}
Expand Down
17 changes: 13 additions & 4 deletions mito.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,17 @@ func Main() int {
fmt.Fprintln(os.Stderr, err)
return 2
}
var env lib.WASMEnvironment
switch {
case strings.EqualFold(mod.Environment, "wasi"):
env = lib.WASIEnvironment
case strings.EqualFold(mod.Environment, "wasm"):
env = lib.UnknownWASMEnvironment
}
modules[modName] = lib.WASMModule{
Object: obj,
Funcs: funcs,
Object: obj,
Funcs: funcs,
Environment: env,
}
}
wasm, err := lib.WASM(nil, modules)
Expand Down Expand Up @@ -422,8 +430,9 @@ type config struct {
}

type wasmModule struct {
Object string `yaml:"obj"` // base64 encoded bytes
Funcs map[string]wasmDecl `yaml:"funcs"`
Object string `yaml:"obj"` // base64 encoded bytes
Funcs map[string]wasmDecl `yaml:"funcs"`
Environment string `yaml:"env"`
}

type wasmDecl struct {
Expand Down
Loading

0 comments on commit 8c2e50c

Please sign in to comment.