package main import ( gcontext "context" "os" "reflect" "github.com/Xe/ln" "github.com/Xe/uuid" "github.com/go-interpreter/wagon/exec" "github.com/go-interpreter/wagon/validate" "github.com/go-interpreter/wagon/wasm" ) type Process struct { id string vm *exec.VM } func NewProcess(vm *exec.VM) *Process { p := &Process{ id: uuid.New(), vm: vm, } return p } func (p Process) importer(name string) (*wasm.Module, error) { switch name { case "env": m := wasm.NewModule() m.Types = &wasm.SectionTypes{ Entries: []wasm.FunctionSig{ { Form: 0, ParamTypes: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI32}, ReturnTypes: []wasm.ValueType{wasm.ValueTypeI32}, }, }, } m.FunctionIndexSpace = []wasm.Function{ { Sig: &m.Types.Entries[0], Host: reflect.ValueOf(p.log), Body: &wasm.FunctionBody{}, }, } m.Export = &wasm.SectionExports{ Entries: map[string]wasm.ExportEntry{ "log": { FieldStr: "log", Kind: wasm.ExternalFunction, Index: 0, }, }, } return m, nil default: f, err := os.Open(name + ".wasm") if err != nil { return nil, err } defer f.Close() m, err := wasm.ReadModule(f, nil) if err != nil { return nil, err } err = validate.VerifyModule(m) if err != nil { return nil, err } return m, nil } } // ID returns the process ID string. func (p Process) ID() string { return p.id } // VM returns the webassembly VM used to execute code. This isn't thread-safe. func (p Process) VM() *exec.VM { return p.vm } func (p *Process) log(ptr int32, len int32) int32 { data := p.vm.Memory()[ptr : ptr+len] ln.Log(gcontext.Background(), ln.F{"data": data, "data_string": string(data), "pid": p.id}) return 0 }