diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9b050fd..d84fe28 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,7 +10,7 @@ jobs: test: strategy: matrix: - go-version: [1.19.x, 1.20.x, 1.21.x] + go-version: [1.20.x, 1.21.x] os: [ubuntu-latest] runs-on: ${{ matrix.os }} diff --git a/go.mod b/go.mod index 4cb48eb..633c4e2 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/google/go-cmp v0.5.8 github.com/google/uuid v1.3.0 github.com/rogpeppe/go-internal v1.8.1 + github.com/wasmerio/wasmer-go v1.0.4 golang.org/x/oauth2 v0.7.0 golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 @@ -24,11 +25,11 @@ require ( github.com/mattn/go-isatty v0.0.12 // indirect github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect github.com/stoewer/go-strcase v1.2.0 // indirect - github.com/stretchr/testify v1.7.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/errgo.v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 3f4ffd9..448bd1c 100644 --- a/go.sum +++ b/go.sum @@ -52,11 +52,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/wasmerio/wasmer-go v1.0.4 h1:MnqHoOGfiQ8MMq2RF6wyCeebKOe84G88h5yv+vmxJgs= +github.com/wasmerio/wasmer-go v1.0.4/go.mod h1:0gzVdSfg6pysA6QVp6iVRPTagC6Wq9pOE8J86WKb2Fk= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -65,8 +67,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -76,17 +78,19 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200821192610-3366bbee4705/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/lib/wasm.go b/lib/wasm.go new file mode 100644 index 0000000..3c98790 --- /dev/null +++ b/lib/wasm.go @@ -0,0 +1,808 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package lib + +import ( + "bytes" + "compress/bzip2" + "compress/gzip" + "encoding/binary" + "errors" + "fmt" + "go/ast" + "go/parser" + "go/token" + gotypes "go/types" + "io" + "math" + "strconv" + "strings" + "unsafe" + + "github.com/google/cel-go/cel" + "github.com/google/cel-go/common/decls" + "github.com/google/cel-go/common/functions" + "github.com/google/cel-go/common/types" + "github.com/google/cel-go/common/types/ref" + "github.com/wasmerio/wasmer-go/wasmer" +) + +type WASMEnvironment int + +const ( + UnknownWASMEnvironment WASMEnvironment = iota + 1 + WASIEnvironment +) + +type WASMModule struct { + Funcs []string + Environment WASMEnvironment + Object []byte +} + +type wasmLib struct { + adapter ref.TypeAdapter + + modules map[string]wasmModule +} + +type wasmModule struct { + inst *wasmer.Instance + mem *wasmer.Memory + alloc wasmer.NativeFunction + free wasmer.NativeFunction + funcs map[string]wasmer.NativeFunction + decls map[string]wasmDecl +} + +type wasmDecl struct { + params []typeMapping + ret typeMapping +} + +func (d wasmDecl) paramTypes() []*types.Type { + typs := make([]*types.Type, 0, len(d.params)) + for _, p := range d.params { + typs = append(typs, p.celType) + } + return typs +} + +type typeMapping struct { + name string + celType *types.Type +} + +// WASM returns a cel.EnvOption to configure foreign functions compiled +// to WASM. +func WASM(adapter ref.TypeAdapter, modules map[string]WASMModule) (cel.EnvOption, error) { + if adapter == nil { + adapter = types.DefaultTypeAdapter + } + mods := make(map[string]wasmModule, len(modules)) + for modName, mod := range modules { + obj, err := expand(mod.Object) + if err != nil { + return nil, err + } + typs, err := funcTypes(modName, mod.Funcs) + if err != nil { + return nil, err + } + inst, funcs, err := compile(obj, typs, mod.Environment) + if err != nil { + return nil, err + } + mem, err := inst.Exports.GetMemory("memory") + if err != nil { + return nil, err + } + decls, err := celTypes(typs) + if err != nil { + return nil, err + } + alloc, _ := inst.Exports.GetFunction("allocate") + free, _ := inst.Exports.GetFunction("deallocate") + mods[modName] = wasmModule{ + inst: inst, + mem: mem, + alloc: alloc, + free: free, + funcs: funcs, + decls: decls, + } + } + return cel.Lib(wasmLib{adapter: adapter, modules: mods}), nil +} + +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]goWASMDecl, 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 + } + 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 + } + funcs := make(map[string]wasmer.NativeFunction, len(decls)+2) + for n := range decls { + funcs[n], err = inst.Exports.GetFunction(n) + if err != nil { + return nil, nil, err + } + } + return inst, funcs, nil +} + +type goWASMDecl struct { + Params []gotypes.Type + Return gotypes.Type +} + +func funcTypes(mod string, funcs []string) (map[string]goWASMDecl, error) { + if len(funcs) == 0 { + return nil, nil + } + + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, "", + `package `+mod+` +import "C" +func `+strings.Join(funcs, "\nfunc "), 0) + if err != nil { + return nil, err + } + config := gotypes.Config{ + IgnoreFuncBodies: true, + FakeImportC: true, + Importer: nil, + } + _, err = config.Check(mod, fset, []*ast.File{f}, nil) + if err != nil { + return nil, err + } + + types := make(map[string]goWASMDecl) + for _, decl := range f.Decls { + decl, ok := decl.(*ast.FuncDecl) + if !ok { + continue + } + params, err := paramTypes(decl.Type.Params.List) + if err != nil { + return nil, fmt.Errorf("invalid signature %s: %w", decl.Name.Name, err) + } + ret, err := returnType(decl.Type.Results.List) + if err != nil { + return nil, fmt.Errorf("invalid signature %s: %w", decl.Name.Name, err) + } + types[decl.Name.Name] = goWASMDecl{Params: params, Return: ret} + } + return types, nil +} + +func paramTypes(list []*ast.Field) ([]gotypes.Type, error) { + var types []gotypes.Type + for _, f := range list { + n, typ, err := fieldType(f) + if err != nil { + return nil, err + } + for i := 0; i < n; i++ { + types = append(types, typ) + } + } + return types, nil +} + +func returnType(list []*ast.Field) (gotypes.Type, error) { + if len(list) != 1 { + return nil, fmt.Errorf("invalid return: must have one return value: have %d", len(list)) + } + n, typ, err := fieldType(list[0]) + if n != 1 { + return nil, fmt.Errorf("invalid return: must have one return value: have %d", n) + } + return typ, err +} + +func fieldType(field *ast.Field) (int, gotypes.Type, error) { + switch typ := field.Type.(type) { + case *ast.ArrayType: + elem, ok := typ.Elt.(*ast.Ident) + if !ok { + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } + var a gotypes.Type + switch len := typ.Len.(type) { + case nil: + a = gotypes.NewSlice(gotypes.Universe.Lookup(elem.Name).Type()) + case *ast.BasicLit: + n, err := strconv.ParseInt(len.Value, 10, 64) + if err != nil { + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } + a = gotypes.NewArray(gotypes.Universe.Lookup(elem.Name).Type(), n) + default: + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } + if len(field.Names) == 0 { + return 1, a, nil + } + return len(field.Names), a, nil + case *ast.StarExpr: + expr, ok := typ.X.(*ast.SelectorExpr) + if !ok || expr.Sel.Name != "char" { + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } + id, ok := expr.X.(*ast.Ident) + if !ok || id.Name != "C" { + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } + if len(field.Names) == 0 { + return 1, cStringType, nil + } + return len(field.Names), cStringType, nil + case *ast.Ident: + if len(field.Names) == 0 { + return 1, gotypes.Universe.Lookup(typ.Name).Type(), nil + } + return len(field.Names), gotypes.Universe.Lookup(typ.Name).Type(), nil + default: + return 0, nil, fmt.Errorf("unsupported type: %T", typ) + } +} + +var ( + // Avoid having to build a Cgo package to be able to use a *C.char sentinel. + // This is more effort than we really need to go to, but it feels better. + cStringType = gotypes.NewPointer(gotypes.NewNamed(gotypes.NewTypeName(0, nil, "_Ctype_char", i8), i8, nil)) + i8 = gotypes.Universe.Lookup("int8").Type() +) + +func celTypes(decls map[string]goWASMDecl) (map[string]wasmDecl, error) { + ds := make(map[string]wasmDecl, len(decls)) + for fn, decl := range decls { + ret, err := celType(decl.Return.String()) + if err != nil { + return nil, err + } + params := make([]typeMapping, len(decl.Params)) + for i, p := range decl.Params { + params[i], err = celType(p.String()) + if err != nil { + return nil, err + } + } + ds[fn] = wasmDecl{ + params: params, + ret: ret, + } + } + return ds, nil +} + +func celType(typ string) (typeMapping, error) { + ct, ok := typesTable[typ] + if !ok { + return typeMapping{}, fmt.Errorf("no type for %s", typ) + } + return typeMapping{name: typ, celType: ct}, nil +} + +var typesTable = map[string]*types.Type{ + "*_Ctype_char": types.StringType, + "bool": types.BoolType, + "float64": types.DoubleType, + "int64": types.IntType, + "string": types.StringType, + + "[]bool": types.NewListType(types.BoolType), + "[]byte": types.BytesType, + "[]float64": types.NewListType(types.DoubleType), + "[]int64": types.NewListType(types.IntType), + "[]string": types.NewListType(types.StringType), +} + +func (l wasmLib) CompileOptions() []cel.EnvOption { + var opts []cel.EnvOption + for modName, mod := range l.modules { + for funcName, decl := range mod.decls { + var binding decls.OverloadOpt + fn := mod.funcs[funcName] + switch len(decl.params) { + case 1: + binding = cel.UnaryBinding(unaryCall(mod.mem, mod.alloc, mod.free, fn, decl, funcName)) + case 2: + binding = cel.BinaryBinding(binaryCall(mod.mem, mod.alloc, mod.free, fn, decl, funcName)) + default: + binding = cel.FunctionBinding(variadicCall(mod.mem, mod.alloc, mod.free, fn, decl, funcName)) + } + opts = append(opts, cel.Function(modName+"_"+funcName, + cel.Overload( + "wasm_"+modName+"_"+funcName, + decl.paramTypes(), + decl.ret.celType, + binding, + ), + )) + } + } + return opts +} + +func (wasmLib) ProgramOptions() []cel.ProgramOption { return nil } + +func unaryCall(mem *wasmer.Memory, alloc, free wasmer.NativeFunction, fn wasmer.NativeFunction, decl wasmDecl, name string) functions.UnaryOp { + return func(arg ref.Val) ref.Val { + val0, free0, err := convertToWASM(arg, decl.params[0], mem, alloc, free) + if err != nil { + return types.NewErr("failed type conversion to wasm for %s: %v", name, err) + } + defer free0() + + return call(mem, alloc, free, fn, decl, name, val0) + } +} + +func binaryCall(mem *wasmer.Memory, alloc, free wasmer.NativeFunction, fn wasmer.NativeFunction, decl wasmDecl, name string) functions.BinaryOp { + return func(arg0, arg1 ref.Val) ref.Val { + val0, free0, err := convertToWASM(arg0, decl.params[0], mem, alloc, free) + if err != nil { + return types.NewErr("failed type conversion to wasm for %s arg 0: %v", name, err) + } + defer free0() + val1, free1, err := convertToWASM(arg1, decl.params[1], mem, alloc, free) + if err != nil { + return types.NewErr("failed type conversion to wasm for %s arg 1: %v", name, err) + } + defer free1() + + return call(mem, alloc, free, fn, decl, name, val0, val1) + } +} + +func variadicCall(mem *wasmer.Memory, alloc, free wasmer.NativeFunction, fn wasmer.NativeFunction, decl wasmDecl, name string) functions.FunctionOp { + return func(args ...ref.Val) ref.Val { + vals := make([]any, len(args)) + for i, arg := range args { + val, free, err := convertToWASM(arg, decl.params[i], mem, alloc, free) + if err != nil { + return types.NewErr("failed type conversion to wasm for %s arg %d: %v", name, i, err) + } + defer free() + vals[i] = val + } + + return call(mem, alloc, free, fn, decl, name, vals...) + } +} + +func call(mem *wasmer.Memory, alloc, free wasmer.NativeFunction, fn wasmer.NativeFunction, decl wasmDecl, name string, args ...any) ref.Val { + wasmArgs, recRet, err := expandArgs(decl.ret, mem, alloc, free, args...) + if err != nil { + return types.NewErr("failed wasm call prep %s(%v): %v", name, errArgs(args), err) + } + ret, err := fn(wasmArgs...) + if err != nil { + return types.NewErr("failed wasm call %s(%v): %v", name, errArgs(args), err) + } + if recRet != nil { + ret = recRet + } + + ret, err = convertFromWASM(ret, decl.ret, mem, free) + if err != nil { + return types.NewErr("failed type conversion from wasm for %s: %v", name, err) + } + + return types.DefaultTypeAdapter.NativeToValue(ret) + +} + +func expandArgs(retMapping typeMapping, mem *wasmer.Memory, alloc, free wasmer.NativeFunction, vals ...any) (args []any, ret func() any, err error) { + var n int + for _, v := range vals { + switch v.(type) { + case stringHeader: + n += 2 + case sliceHeader: + n += 3 + default: + n++ + } + } + switch retMapping.name { + case "string": + var addr int32 + args, addr, err = allocRet(n, unsafe.Sizeof(stringHeader{}), alloc) + if err != nil { + return nil, nil, err + } + ret = func() any { + m := mem.Data() + h := m[addr : int(addr)+int(unsafe.Sizeof(stringHeader{}))] + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := string(m[ptr : ptr+len]) + free(addr, int(unsafe.Sizeof(stringHeader{}))) + return s + } + default: + if !strings.HasPrefix(retMapping.name, "[]") { + args = make([]any, 0, n) + break + } + var addr int32 + args, addr, err = allocRet(n, unsafe.Sizeof(sliceHeader{}), alloc) + if err != nil { + return nil, nil, err + } + m := mem.Data() + h := m[addr : int(addr)+int(unsafe.Sizeof(sliceHeader{}))] + switch strings.TrimPrefix(retMapping.name, "[]") { + case "bool": + ret = func() any { + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := make([]bool, len) + o := m[ptr : ptr+len] + copy(s, *(*[]bool)(unsafe.Pointer(&o))) + free(addr, int(unsafe.Sizeof(sliceHeader{}))) + return s + } + case "byte": + ret = func() any { + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := bytes.Clone(m[ptr : ptr+len]) + free(addr, int(unsafe.Sizeof(stringHeader{}))) + return s + } + case "float64": + ret = func() any { + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := make([]float64, len) + for i := range s { + s[i] = math.Float64frombits(binary.LittleEndian.Uint64(m[ptr:])) + ptr += int32(unsafe.Sizeof(float64(0))) + } + free(addr, int(unsafe.Sizeof(sliceHeader{}))) + return s + } + case "int64": + ret = func() any { + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := make([]int64, len) + for i := range s { + s[i] = int64(binary.LittleEndian.Uint64(m[ptr:])) + ptr += int32(unsafe.Sizeof(int64(0))) + } + free(addr, int(unsafe.Sizeof(sliceHeader{}))) + return s + } + case "string": + ret = func() any { + ptr := int32(binary.LittleEndian.Uint32(h[:4])) + len := int32(binary.LittleEndian.Uint32(h[4:8])) + s := make([]string, len) + for i := range s { + sptr := int32(binary.LittleEndian.Uint64(m[ptr:])) + slen := int32(binary.LittleEndian.Uint64(m[ptr+int32(unsafe.Sizeof(int32(0))):])) + s[i] = string(m[sptr : sptr+slen]) + ptr += int32(unsafe.Sizeof(stringHeader{})) + } + free(addr, int(unsafe.Sizeof(sliceHeader{}))) + return s + } + } + } + for _, v := range vals { + switch v := v.(type) { + case stringHeader: + args = append(args, v.ptr, v.len) + case sliceHeader: + args = append(args, v.ptr, v.len, v.cap) + case bool: + args = append(args, i32bool(v)) + default: + args = append(args, v) + } + } + return args, ret, nil +} + +func i32bool(t bool) int32 { + if t { + return 1 + } + return 0 +} + +func allocRet(nargs int, size uintptr, alloc wasmer.NativeFunction) (args []any, retAddr int32, err error) { + args = make([]any, 1, nargs+1) + ptr, err := alloc(int(size)) + if err != nil { + return nil, 0, err + } + addr, ok := ptr.(int32) + if !ok { + return nil, 0, errors.New("could not allocate return slot") + } + args[0] = addr + return args, addr, nil +} + +func convertToWASM(arg ref.Val, typ typeMapping, mem *wasmer.Memory, alloc, free wasmer.NativeFunction) (any, func(), error) { + val := arg.Value() + switch typ.celType { + case types.BoolType, types.DoubleType, types.IntType: + return val, noop, nil + case types.BytesType: + switch val := val.(type) { + case []byte: + switch typ.name { + case "[]byte": + return byteslice(val, mem, alloc, free) + default: + panic("unreachable") + } + default: + return nil, noop, fmt.Errorf("%v is not a bytes: %[1]T", val) + } + case types.StringType: + switch val := val.(type) { + case string: + switch typ.name { + case "*_Ctype_char": + return cstring(val, mem, alloc, free) + case "string": + return nativestring(val, mem, alloc, free) + default: + panic("unreachable") + } + default: + return nil, noop, fmt.Errorf("%v is not a string: %[1]T", val) + } + default: + panic("invalid type") + } +} + +func convertFromWASM(ret any, typ typeMapping, mem *wasmer.Memory, free wasmer.NativeFunction) (any, error) { + if ret, ok := ret.(func() any); ok { + return ret(), nil + } + switch typ.celType { + case types.BoolType, types.DoubleType, types.IntType: + return ret, nil + case types.StringType, types.BytesType: + switch ret := ret.(type) { + case int32: + b, err := gostring(ret, mem, free) + if err != nil { + return nil, err + } + if typ.celType == types.StringType { + return string(b), nil + } + return bytes.Clone(b), nil + default: + return nil, fmt.Errorf("%v is not a pointer: %[1]T", ret) + } + default: + panic("invalid type") + } +} + +func cstring(s string, mem *wasmer.Memory, alloc, free wasmer.NativeFunction) (int32, func(), error) { + if alloc == nil { + return 0, noop, errors.New("no allocator") + } + if free == nil { + return 0, noop, errors.New("no deallocator") + } + ptr, err := alloc(len(s) + 1) + if err != nil { + return 0, noop, err + } + addr, ok := ptr.(int32) + if !ok { + return 0, noop, errors.New("null pointer") + } + data := mem.Data()[addr : int(addr)+len(s)+1] + copy(data, s) + data[len(s)] = 0 + return addr, func() { + free(addr, len(s)+1) + }, nil +} + +type stringHeader struct { + ptr int32 + len int32 +} + +type sliceHeader struct { + ptr int32 + len int32 + cap int32 +} + +func nativestring(s string, mem *wasmer.Memory, alloc, free wasmer.NativeFunction) (stringHeader, func(), error) { + if alloc == nil { + return stringHeader{}, noop, errors.New("no allocator") + } + if free == nil { + return stringHeader{}, noop, errors.New("no deallocator") + } + ptr, err := alloc(len(s)) + if err != nil { + return stringHeader{}, noop, err + } + addr, ok := ptr.(int32) + if !ok { + return stringHeader{}, noop, errors.New("null pointer") + } + data := mem.Data()[addr : int(addr)+len(s)] + copy(data, s) + return stringHeader{ptr: int32(addr), len: int32(len(s))}, func() { + free(addr, len(s)) + }, nil +} + +func byteslice(b []byte, mem *wasmer.Memory, alloc, free wasmer.NativeFunction) (sliceHeader, func(), error) { + if alloc == nil { + return sliceHeader{}, noop, errors.New("no allocator") + } + if free == nil { + return sliceHeader{}, noop, errors.New("no deallocator") + } + ptr, err := alloc(len(b)) + if err != nil { + return sliceHeader{}, noop, err + } + addr, ok := ptr.(int32) + if !ok { + return sliceHeader{}, noop, errors.New("null pointer") + } + data := mem.Data()[addr : int(addr)+len(b)] + copy(data, b) + return sliceHeader{ptr: int32(addr), len: int32(len(b)), cap: int32(len(b))}, func() { + free(addr, len(b)) + }, nil +} + +func noop() {} + +func gostring(addr int32, mem *wasmer.Memory, free wasmer.NativeFunction) ([]byte, error) { + if free == nil { + return nil, errors.New("no deallocator") + } + data := mem.Data() + b, _, ok := bytes.Cut(data[addr:], []byte{0}) + if !ok { + return nil, errors.New("no null") + } + _, err := free(addr, len(b)+1) + return b, err +} + +func errArg(v any) string { + const limit = 10 + + buf := limitWriter{limit: limit} + fmt.Fprintf(&buf, "%#v", v) + return buf.String() +} + +func errArgs(v []any) string { + const ( + limit = 10 + more = "..." + ) + n := len(v) + if n > limit { + n = limit + } + args := make([]string, n) + if len(v) > len(args) { + n-- + args[n] = more + } + for i := range args[:n] { + args[i] = errArg(v[i]) + } + return strings.Join(args, ", ") +} + +type limitWriter struct { + buf strings.Builder + limit int +} + +func (w *limitWriter) String() string { + return w.buf.String() +} + +func (w *limitWriter) Write(b []byte) (int, error) { + const more = "..." + n := w.limit - w.buf.Len() + if n <= 0 { + w.buf.WriteString(more) + return len(more), io.EOF + } + if n < len(b) { + n -= len(more) + } + if n < 0 { + n = 0 + } else if n > len(b) { + n = len(b) + } + n, err := w.buf.Write(b[:n]) + if n < len(b) { + w.buf.WriteString(more) + } + return n, err +} diff --git a/mito.go b/mito.go index d31ce3b..3487f2f 100644 --- a/mito.go +++ b/mito.go @@ -26,6 +26,7 @@ import ( "compress/gzip" "context" "crypto/tls" + "encoding/base64" "encoding/json" "errors" "flag" @@ -111,6 +112,34 @@ func Main() int { } libs = append(libs, lib.Regexp(regexps)) } + if len(cfg.WASM) != 0 { + modules := make(map[string]lib.WASMModule, len(cfg.WASM)) + for modName, mod := range cfg.WASM { + obj, err := base64.StdEncoding.DecodeString(mod.Object) + if err != nil { + 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{ + Funcs: mod.Funcs, + Object: obj, + Environment: env, + } + } + wasm, err := lib.WASM(nil, modules) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return 2 + } + libs = append(libs, wasm) + } if len(cfg.XSDs) != 0 { xsds := make(map[string]string) for name, path := range cfg.XSDs { @@ -388,10 +417,22 @@ func toUpper(p []byte) { type config struct { Globals map[string]interface{} `yaml:"globals"` Regexps map[string]string `yaml:"regexp"` + WASM map[string]wasmModule `yaml:"wasm"` XSDs map[string]string `yaml:"xsd"` Auth *authConfig `yaml:"auth"` } +type wasmModule struct { + Object string `yaml:"obj"` // base64 encoded bytes + Funcs []string `yaml:"funcs"` + Environment string `yaml:"env"` +} + +type wasmDecl struct { + Params []string `yaml:"params"` + Return string `yaml:"return"` +} + type authConfig struct { Basic *lib.BasicAuth `yaml:"basic"` OAuth2 *oAuth2 `yaml:"oauth2"` diff --git a/testdata/wasm.txt b/testdata/wasm.txt new file mode 100644 index 0000000..0f6cd0c --- /dev/null +++ b/testdata/wasm.txt @@ -0,0 +1,1363 @@ +mito -cfg cfg.yaml src.cel +! stderr . +cmp stdout want.txt + +-- src.cel -- +{ + "go_add_one": go_testmod_add_one(2), + "go_sum": go_testmod_sum(2, 3), + "go_concat_c": go_testmod_concat_c_string("hello, ", "world"), + "go_concat_go": go_testmod_concat_go_string("hello, ", "world"), + "go_concat_bytes": go_testmod_concat_bytes(b"hello, ", b"world"), + "go_bool_list": go_testmod_bool_list(true, false, true, false, false, true, true, false), + "go_double_list": go_testmod_double_list(1.2, 3.4), + "go_int_list": go_testmod_int_list(1, 2), + "go_comma_split": go_testmod_comma_split("one,two,three"), + "rust_add_one": rust_testmod_add_one(2), + "rust_sum": rust_testmod_sum(2, 3), + "rust_concat": rust_testmod_concat("hello, ", "world"), +} +-- want.txt -- +{ + "go_add_one": 3, + "go_bool_list": [ + true, + false, + true, + false, + false, + true, + true, + false + ], + "go_comma_split": [ + "one", + "two", + "three" + ], + "go_concat_bytes": "aGVsbG8sIHdvcmxk", + "go_concat_c": "hello, world", + "go_concat_go": "hello, world", + "go_double_list": [ + 1.2, + 3.4 + ], + "go_int_list": [ + 1, + 2 + ], + "go_sum": 5, + "rust_add_one": 3, + "rust_concat": "hello, world", + "rust_sum": 5 +} +-- cfg.yaml -- +wasm: + go_testmod: + funcs: + - add_one(x int64) int64 + - bool_list(a, b, c, d, e, f, g, h bool) []bool + - comma_split(s string) []string + - concat_c_string(a, b *C.char) *C.char + - concat_bytes(a, b []byte) []byte + - concat_go_string(a, b string) string + - double_list(a, b float64) []float64 + - int_list(a, b int64) []int64 + - sum(x, y int64) int64 + env: wasi + obj: | + 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 + YYKkKW9wJ5reG+IoC5MHoyE6NlpRT08X6DWYCQs0/89VoFtsipepdX0UkhCFvAA6OOO35tR0Gl7K + ulInV3xidB9zQ6WTvMltgUqatAbEQeb8HB2jx4IEd53R8ltPTfdIwtmjkwrjO3hwnADYNEyXcwXT + Pl3LH1WJgYwjb76Y2IiluoTxpIXDo023WdkXluHAm2SaquOXx1ZN1kISpCi2FjetzrnwJckClbCs + K/QKqic9XemgMZHumZHz0z2FGbmC15JerMeC3u1rlJRROgx8jXDyJopt9jAaVdbCDBazUQlEbX98 + z2bZuBr6Qxh01Wo6KlYXF+Uuty5aFqPSfVrDe6+1TbLnJlLJnPCXxyklOsMP6FeuHBtVGqLd28ud + wWw1VLg0cFfQ/mpW3RftSjkVEq4Im6w1E7hI0Op466eEeC3zNyAlzTXk1MKnl9mzUoR9OgbveZjR + 8b7oLFaidc4waHiQ5o7aqmLuquR3a0CtmWws88bjoEBC4qdrUN67U8L1OjYqX8IoKtBnjqe0t/xr + VFRub95MdIMIL5RPLJlI3ayUra7DvV+JecgvdtPbZcEbXlFEQM0Zv2AohW0+ZZpfbq+7u5M6tFhl + nzHN2D/4tOn4W0pZITIK9ZVqUjeVE3tIGXvE9kiOFSXbMM9x//3gTcnno+o8JqijEGB1wwsqaNIL + qh5T4ciK24imGOq9HVFvq7+rS6rzPV57UcRYfmk/SVVdTHamS8umTZpEZdMmT6ZdxM8p6Ue3N7T1 + llYoNut5XyCLdeWcTK53ulc5sfGAiY0TqaVGqMbOdGFBRzpZKIqSy+truosqmm0wvkH94Jxck9cR + bUNHviAnef2AtmK2q0HnTK7vJ4O5BiHp/wLHSbEXkDYCAA== + rust_testmod: + funcs: + - add_one(x int64) int64 + - concat(a, b *C.char) *C.char + - sum(x, y int64) int64 + env: wasm + obj: | + AGFzbQEAAAABZhBgAn9/AGADf39/AX9gAn9/AX9gBH9/f38AYAN/f38AYAF+AX5gAn5+AX5gAX8Bf2AE + f39/fwF/YAF/AGAAAX9gBn9/f39/fwBgBX9/f39/AX9gAABgBn9/f39/fwF/YAN+f38BfwNsawMEBQYH + AAICBAgAAAAABAIJCQkJAgABAwAJAAoJBwACCQkAAgQICQAAAAALAAACAgcHBwoHBwcJBwcAAAAABAIC + BwoHBwcHBwcHAgcEDAgBAgcDAA0AAAAAAgkABAIBDgAHBwcCDA8BBwcBBAUBcAEUFAUDAQARBhkDfwFB + gIDAAAt/AEG5iMAAC38AQcCIwAALB1YIBm1lbW9yeQIAB2FkZF9vbmUAAgNzdW0AAwhhbGxvY2F0ZQAE + CmRlYWxsb2NhdGUABQZjb25jYXQABgpfX2RhdGFfZW5kAwELX19oZWFwX2Jhc2UDAgkZAQBBAQsTXSIS + FhQPDRAMKSoTJygRC1laYArpgQFrxQEAAkACQCABRQ0AIAJBf0wNAQJAAkAgAygCBEUNAAJAIANBCGoo + AgAiAQ0AQQAtANWEQBogAkEBEAchAQwCCyADKAIAIAFBASACEAkhAQwBC0EALQDVhEAaIAJBARAHIQEL + AkAgAUUNACAAIAE2AgQgAEEIaiACNgIAIABBADYCAA8LIABBATYCBCAAQQhqIAI2AgAgAEEBNgIADwsg + AEEANgIEIABBCGogAjYCACAAQQE2AgAPCyAAQQA2AgQgAEEBNgIAC8oBAQJ/IwBBIGsiAyQAAkACQCAB + IAJqIgIgAUkNACAAKAIEIgFBAXQiBCACIAQgAksbIgJBCCACQQhLGyICQX9zQR92IQQCQAJAIAENACAD + QQA2AhgMAQsgAyABNgIcIANBATYCGCADIAAoAgA2AhQLIANBCGogBCACIANBFGoQACADKAIMIQECQCAD + KAIIDQAgACACNgIEIAAgATYCAAwCCyABQYGAgIB4Rg0BIAFFDQAgASADQRBqKAIAEFMACxBUAAsgA0Eg + aiQACwcAIABCAXwLBwAgASAAfAs7AQF/AkAgAA0AQQEPCwJAAkAgAEF/TA0AQQAtANWEQBogAEEBEAci + AUUNASABDwsQVAALQQEgABBTAAsSAAJAIAFFDQAgACABQQEQCAsLngQBCH8jAEEwayICJABBASEDQQEh + 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 + Ynl0ZXMgZmFpbGVkAABEABAAFQAAAFkAEAANAAAAbGlicmFyeS9zdGQvc3JjL2FsbG9jLnJzeAAQABgA + AABiAQAACQAAAGxpYnJhcnkvc3RkL3NyYy9wYW5pY2tpbmcucnOgABAAHAAAAFMCAAAfAAAAoAAQABwA + AABUAgAAHgAAAAMAAAAMAAAABAAAAAcAAAAIAAAACAAAAAQAAAAJAAAACAAAAAgAAAAEAAAACgAAAAsA + AAAMAAAAEAAAAAQAAAANAAAADgAAAA8AAAAAAAAAAQAAABAAAABsaWJyYXJ5L2FsbG9jL3NyYy9yYXdf + dmVjLnJzY2FwYWNpdHkgb3ZlcmZsb3cAAABQARAAEQAAADQBEAAcAAAAFgIAAAUAAAASAAAAAAAAAAEA + AAATAAAAMDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2 + MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2 + NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2 + ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTkA9C4EbmFtZQHsLmsALmFsbG9jOjpyYXdfdmVjOjpmaW5p + c2hfZ3Jvdzo6aGFmMjBhN2I1ODU5MTRjMGYBTmFsbG9jOjpyYXdfdmVjOjpSYXdWZWM8VCxBPjo6cmVz + ZXJ2ZTo6ZG9fcmVzZXJ2ZV9hbmRfaGFuZGxlOjpoODVjYjQ3YzUxODZjZDA2OQIHYWRkX29uZQMDc3Vt + BAhhbGxvY2F0ZQUKZGVhbGxvY2F0ZQYGY29uY2F0BwxfX3J1c3RfYWxsb2MIDl9fcnVzdF9kZWFsbG9j + CQ5fX3J1c3RfcmVhbGxvYwoaX19ydXN0X2FsbG9jX2Vycm9yX2hhbmRsZXILMTxUIGFzIGNvcmU6OmFu + eTo6QW55Pjo6dHlwZV9pZDo6aDExNDY1YjNlOGRjZDYyNDkMMTxUIGFzIGNvcmU6OmFueTo6QW55Pjo6 + dHlwZV9pZDo6aDk0YzM3YzBhM2UzNTcwNWQNMTxUIGFzIGNvcmU6OmFueTo6QW55Pjo6dHlwZV9pZDo6 + aGU1Zjc3MTE2OTQwYzhjYjUOTmFsbG9jOjpyYXdfdmVjOjpSYXdWZWM8VCxBPjo6cmVzZXJ2ZTo6ZG9f + cmVzZXJ2ZV9hbmRfaGFuZGxlOjpoMDdiMDU3NmM0Y2I2Mjg2Yg8uY29yZTo6Zm10OjpXcml0ZTo6d3Jp + dGVfZm10OjpoNDMyZWI5NTc0NzY2MjliYRB8Y29yZTo6cHRyOjpkcm9wX2luX3BsYWNlPCgmc3RkOjpm + Zmk6Om9zX3N0cjo6T3NTdHJpbmcsJmNvcmU6Om9wdGlvbjo6T3B0aW9uPHN0ZDo6ZmZpOjpvc19zdHI6 + Ok9zU3RyaW5nPik+OjpoZDMzYjkwNmU3YmE2OGRiZBEvY29yZTo6cHRyOjpkcm9wX2luX3BsYWNlPCgp + Pjo6aDVmNDZlZDVlNzY5ZmRlYzUSQmNvcmU6OnB0cjo6ZHJvcF9pbl9wbGFjZTxhbGxvYzo6c3RyaW5n + OjpTdHJpbmc+OjpoYjk0MzI4MTJjN2VlZWQwMBNlY29yZTo6cHRyOjpkcm9wX2luX3BsYWNlPHN0ZDo6 + cGFuaWNraW5nOjpiZWdpbl9wYW5pY19oYW5kbGVyOjpGb3JtYXRTdHJpbmdQYXlsb2FkPjo6aGY5YWJi + ZDQ2MTE5YmIwMDAUSjxhbGxvYzo6c3RyaW5nOjpTdHJpbmcgYXMgY29yZTo6Zm10OjpXcml0ZT46Ondy + aXRlX2NoYXI6Omg4NTQ0MTU5NjhkYmZiNWVlFUBhbGxvYzo6cmF3X3ZlYzo6UmF3VmVjPFQsQT46OnJl + c2VydmVfZm9yX3B1c2g6Omg5M2U0YWEzYmI5ZDVmMTM5Fkk8YWxsb2M6OnN0cmluZzo6U3RyaW5nIGFz + IGNvcmU6OmZtdDo6V3JpdGU+Ojp3cml0ZV9zdHI6Omg1NDRiMDBjMzA5MTY1YTRkFy5hbGxvYzo6cmF3 + X3ZlYzo6ZmluaXNoX2dyb3c6OmhlOTA0ZDQwZWU0MWUwZDY2GEFkbG1hbGxvYzo6ZGxtYWxsb2M6OkRs + bWFsbG9jPEE+OjpkaXNwb3NlX2NodW5rOjpoNDNiZjI4YmQwMTM4NjlkMhlGZGxtYWxsb2M6OmRsbWFs + bG9jOjpEbG1hbGxvYzxBPjo6dW5saW5rX2xhcmdlX2NodW5rOjpoNGZhNDdmMWM0MTZiNjM3ZBpGZGxt + YWxsb2M6OmRsbWFsbG9jOjpEbG1hbGxvYzxBPjo6aW5zZXJ0X2xhcmdlX2NodW5rOjpoMTIwNGZkNjhj + ZmU5MGViNhtLZGxtYWxsb2M6OmRsbWFsbG9jOjpEbG1hbGxvYzxBPjo6cmVsZWFzZV91bnVzZWRfc2Vn + bWVudHM6OmhlMzVkYzlhMGY3NzNmMjNlHDhkbG1hbGxvYzo6ZGxtYWxsb2M6OkRsbWFsbG9jPEE+Ojpm + cmVlOjpoOTNhMDUyZmVmMTUyYTJjMx06ZGxtYWxsb2M6OmRsbWFsbG9jOjpEbG1hbGxvYzxBPjo6bWFs + bG9jOjpoZDgwNGZjZWU1YTBjMmIwYh48ZGxtYWxsb2M6OmRsbWFsbG9jOjpEbG1hbGxvYzxBPjo6aW5p + dF90b3A6Omg0ODMzMjk4MjQ3ODk5MWNkHzxkbG1hbGxvYzo6ZGxtYWxsb2M6OkRsbWFsbG9jPEE+Ojpt + ZW1hbGlnbjo6aGRmYWI2M2FhMTZlMTc1NDMgSXN0ZDo6c3lzX2NvbW1vbjo6YmFja3RyYWNlOjpfX3J1 + c3RfZW5kX3Nob3J0X2JhY2t0cmFjZTo6aDcxZjUwNGQ0NmEyMDNkODghQ3N0ZDo6cGFuaWNraW5nOjpi + ZWdpbl9wYW5pY19oYW5kbGVyOjp7e2Nsb3N1cmV9fTo6aDgyNDE1ZmUzNWIwZTIwMDEiN3N0ZDo6YWxs + b2M6OmRlZmF1bHRfYWxsb2NfZXJyb3JfaG9vazo6aDAyMDEzNWMxMGZhNTZjMjYjC19fcmRsX2FsbG9j + JA1fX3JkbF9kZWFsbG9jJQ1fX3JkbF9yZWFsbG9jJhFydXN0X2JlZ2luX3Vud2luZCd0PHN0ZDo6cGFu + aWNraW5nOjpiZWdpbl9wYW5pY19oYW5kbGVyOjpGb3JtYXRTdHJpbmdQYXlsb2FkIGFzIGNvcmU6OnBh + bmljOjpQYW5pY1BheWxvYWQ+Ojp0YWtlX2JveDo6aDFiZGNlZjkyNTBiOTAzYWIobzxzdGQ6OnBhbmlj + a2luZzo6YmVnaW5fcGFuaWNfaGFuZGxlcjo6Rm9ybWF0U3RyaW5nUGF5bG9hZCBhcyBjb3JlOjpwYW5p + Yzo6UGFuaWNQYXlsb2FkPjo6Z2V0OjpoNDRkYTgxNjA1OWI3M2EzOClxPHN0ZDo6cGFuaWNraW5nOjpi + ZWdpbl9wYW5pY19oYW5kbGVyOjpTdGF0aWNTdHJQYXlsb2FkIGFzIGNvcmU6OnBhbmljOjpQYW5pY1Bh + eWxvYWQ+Ojp0YWtlX2JveDo6aGM1ODE5YzYzOWFhMTY3MjEqbDxzdGQ6OnBhbmlja2luZzo6YmVnaW5f + cGFuaWNfaGFuZGxlcjo6U3RhdGljU3RyUGF5bG9hZCBhcyBjb3JlOjpwYW5pYzo6UGFuaWNQYXlsb2Fk + Pjo6Z2V0OjpoMDgyZjdmNTE4NDQ3NTIwNis3c3RkOjpwYW5pY2tpbmc6OnJ1c3RfcGFuaWNfd2l0aF9o + b29rOjpoYzIwZWFkZGVkNmJmZTY4NywKcnVzdF9wYW5pYy0IX19yZ19vb20uEl9fcnVzdF9zdGFydF9w + YW5pYy8vZGxtYWxsb2M6OmRsbWFsbG9jOjphbGlnbl91cDo6aDI0YjE0NzM2YzE2OGZlOWYwMGRsbWFs + bG9jOjpkbG1hbGxvYzo6bGVmdF9iaXRzOjpoMjIzNjBhMzFlNmNjYTIzMDEwZGxtYWxsb2M6OmRsbWFs + bG9jOjpsZWFzdF9iaXQ6OmgxMWQwNmFmZjA5YmYzNjkyMj9kbG1hbGxvYzo6ZGxtYWxsb2M6OmxlZnRz + aGlmdF9mb3JfdHJlZV9pbmRleDo6aDMwZjM3ZmQ3M2ZjYmRlYmQzPGRsbWFsbG9jOjpkbG1hbGxvYzo6 + Q2h1bms6OmZlbmNlcG9zdF9oZWFkOjpoY2UyODgwZjAzYjYzYWIyODQyZGxtYWxsb2M6OmRsbWFsbG9j + OjpDaHVuazo6c2l6ZTo6aDhjMzM0NWI3MTc2Zjk5Y2U1NGRsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6 + OmNpbnVzZTo6aGJmNGRhYmJiNWFhZTgwMjM2NGRsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OnBpbnVz + ZTo6aGYxY2MzYWIzOGUzN2NiNDg3OmRsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OmNsZWFyX3BpbnVz + ZTo6aGE0ZWI4YzIxNzA0MDlhYmY4M2RsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OmludXNlOjpoZjll + NTFiZTU0MGFlNGZmZjk1ZGxtYWxsb2M6OmRsbWFsbG9jOjpDaHVuazo6bW1hcHBlZDo6aDljMDQ1ZWJm + YTBlZTI2MjE6N2RsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OnNldF9pbnVzZTo6aGZjOTczNmIyYmRj + MTRkNmE7QmRsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OnNldF9pbnVzZV9hbmRfcGludXNlOjpoZTlj + OTIyOWMyNjUzYTYxZTxQZGxtYWxsb2M6OmRsbWFsbG9jOjpDaHVuazo6c2V0X3NpemVfYW5kX3BpbnVz + ZV9vZl9pbnVzZV9jaHVuazo6aDNkNzAxNThmMzY5MTFiMWY9T2RsbWFsbG9jOjpkbG1hbGxvYzo6Q2h1 + bms6OnNldF9zaXplX2FuZF9waW51c2Vfb2ZfZnJlZV9jaHVuazo6aDlmYTZjMTExMTc0YWJmMWE+QmRs + bWFsbG9jOjpkbG1hbGxvYzo6Q2h1bms6OnNldF9mcmVlX3dpdGhfcGludXNlOjpoYTU2YzBmNmZjZTI2 + NjhhMj85ZGxtYWxsb2M6OmRsbWFsbG9jOjpDaHVuazo6cGx1c19vZmZzZXQ6OmgzN2U2NTlkYWMwN2I0 + NjU4QDpkbG1hbGxvYzo6ZGxtYWxsb2M6OkNodW5rOjptaW51c19vZmZzZXQ6Omg4NGFjNDRkMDE1ZGRi + Njk0QTRkbG1hbGxvYzo6ZGxtYWxsb2M6OkNodW5rOjp0b19tZW06Omg1NjZlMzM2NDY2OTI1ZGIzQjhk + bG1hbGxvYzo6ZGxtYWxsb2M6OkNodW5rOjptZW1fb2Zmc2V0OjpoYjU4ZGU5ZmFhNjMyOTUwN0M2ZGxt + YWxsb2M6OmRsbWFsbG9jOjpDaHVuazo6ZnJvbV9tZW06OmgyZTA0OGJmNmI2YmY5N2JlREBkbG1hbGxv + Yzo6ZGxtYWxsb2M6OlRyZWVDaHVuazo6bGVmdG1vc3RfY2hpbGQ6OmhlNTZiMmZhYTRmMGZlNTlmRTdk + bG1hbGxvYzo6ZGxtYWxsb2M6OlRyZWVDaHVuazo6Y2h1bms6OmgzZDg4ZDY3NzFjYzA0YzQ4RjZkbG1h + bGxvYzo6ZGxtYWxsb2M6OlRyZWVDaHVuazo6bmV4dDo6aDU5YTkxMTJkM2VmODQ5NDFHNmRsbWFsbG9j + OjpkbG1hbGxvYzo6VHJlZUNodW5rOjpwcmV2OjpoZjlmMzNkNjkwMTI1Y2UzYkg5ZGxtYWxsb2M6OmRs + bWFsbG9jOjpTZWdtZW50Ojppc19leHRlcm46OmgyNWQzNjk4YTM4NzJjMTg3STlkbG1hbGxvYzo6ZGxt + YWxsb2M6OlNlZ21lbnQ6OnN5c19mbGFnczo6aGYxNGY0NzNiYWY3M2FkZGJKNWRsbWFsbG9jOjpkbG1h + bGxvYzo6U2VnbWVudDo6aG9sZHM6Omg0ZjAxMzExZDFkMzhiNTY0SzNkbG1hbGxvYzo6ZGxtYWxsb2M6 + OlNlZ21lbnQ6OnRvcDo6aDUyMGVjNmM4YTFhYjk4MjBMSDxkbG1hbGxvYzo6c3lzOjpTeXN0ZW0gYXMg + ZGxtYWxsb2M6OkFsbG9jYXRvcj46OmFsbG9jOjpoM2IxOTIxNTRlZDU2ZTkxYU1IPGRsbWFsbG9jOjpz + eXM6OlN5c3RlbSBhcyBkbG1hbGxvYzo6QWxsb2NhdG9yPjo6cmVtYXA6Omg1ZDk5NzJmMDY5ZTliZjAy + Tkw8ZGxtYWxsb2M6OnN5czo6U3lzdGVtIGFzIGRsbWFsbG9jOjpBbGxvY2F0b3I+OjpmcmVlX3BhcnQ6 + OmhhY2NkYTZlNjlkMjcxMTYyT0c8ZGxtYWxsb2M6OnN5czo6U3lzdGVtIGFzIGRsbWFsbG9jOjpBbGxv + Y2F0b3I+OjpmcmVlOjpoMDQzMjVjYWYxZWNiYmNlMlBTPGRsbWFsbG9jOjpzeXM6OlN5c3RlbSBhcyBk + bG1hbGxvYzo6QWxsb2NhdG9yPjo6Y2FuX3JlbGVhc2VfcGFydDo6aDE3MWE2ZWFjMWRmYTYwOTlRTDxk + bG1hbGxvYzo6c3lzOjpTeXN0ZW0gYXMgZGxtYWxsb2M6OkFsbG9jYXRvcj46OnBhZ2Vfc2l6ZTo6aGNj + YTI2NTg2NzU4NTUwMTFSLmFsbG9jOjpyYXdfdmVjOjpmaW5pc2hfZ3Jvdzo6aDljYWI2ZjhlNzQ3MzMw + ZjRTM2FsbG9jOjphbGxvYzo6aGFuZGxlX2FsbG9jX2Vycm9yOjpoNjc5NGJhZjkzZGQ5MTc3M1Q0YWxs + b2M6OnJhd192ZWM6OmNhcGFjaXR5X292ZXJmbG93OjpoODQ3YTY4MmI0MmRkNjg0ZlVAYWxsb2M6OnJh + d192ZWM6OlJhd1ZlYzxULEE+OjpyZXNlcnZlX2Zvcl9wdXNoOjpoZGNhZjg0YjQwOGQwMjcwOVY9YWxs + b2M6OmFsbG9jOjpoYW5kbGVfYWxsb2NfZXJyb3I6OnJ0X2Vycm9yOjpoZTE4NGRjMTdlZGFkYzUxNVdC + YWxsb2M6OmZmaTo6Y19zdHI6OkNTdHJpbmc6Ol9mcm9tX3ZlY191bmNoZWNrZWQ6OmhjMzE4ZTZhMjZh + Y2RkMjUxWEFhbGxvYzo6ZmZpOjpjX3N0cjo6Q1N0cmluZzo6ZnJvbV92ZWNfdW5jaGVja2VkOjpoNmQ2 + MjE3NDExMWQ1OWUwY1k5Y29yZTo6b3BzOjpmdW5jdGlvbjo6Rm5PbmNlOjpjYWxsX29uY2U6Omg4ZTUz + MWIwYjdiZjY2MjBjWj1jb3JlOjpwdHI6OmRyb3BfaW5fcGxhY2U8Y29yZTo6Zm10OjpFcnJvcj46Omhj + M2ZmNDlhZDM0NDg5MmNhWy1jb3JlOjpwYW5pY2tpbmc6OnBhbmljX2ZtdDo6aDdhMzY4Mzg1OTM2ODg4 + ZGNcKWNvcmU6OnBhbmlja2luZzo6cGFuaWM6Omg3YmJlYTM3NzNiNzUyMjM1XU5jb3JlOjpmbXQ6Om51 + bTo6aW1wOjo8aW1wbCBjb3JlOjpmbXQ6OkRpc3BsYXkgZm9yIHUzMj46OmZtdDo6aDNmMDRjNzk5Y2Ux + OWZkNTZeI2NvcmU6OmZtdDo6d3JpdGU6Omg3YjYyYTAyZmIwNDdkMDU1XzVjb3JlOjpmbXQ6OkZvcm1h + dHRlcjo6cGFkX2ludGVncmFsOjpoZWEyZGJkMDA1YWI2OTA5M2AxPFQgYXMgY29yZTo6YW55OjpBbnk+ + Ojp0eXBlX2lkOjpoNDJmYzcxNjUyMzg3NDZkZmE+Y29yZTo6cGFuaWM6OnBhbmljX2luZm86OlBhbmlj + SW5mbzo6bWVzc2FnZTo6aDY4MjA3ZjhiZjZlMDViZGNiP2NvcmU6OnBhbmljOjpwYW5pY19pbmZvOjpQ + YW5pY0luZm86OmxvY2F0aW9uOjpoZDM1ZjE1NDcwNDZkYTY5YWNBY29yZTo6cGFuaWM6OnBhbmljX2lu + Zm86OlBhbmljSW5mbzo6Y2FuX3Vud2luZDo6aGJkMGMzYTEwNzcwMDk3M2JkM2NvcmU6OnN0cjo6Y291 + bnQ6OmRvX2NvdW50X2NoYXJzOjpoNjY0ZmNlODQ1OGM4NDZjYmVDY29yZTo6Zm10OjpGb3JtYXR0ZXI6 + OnBhZF9pbnRlZ3JhbDo6d3JpdGVfcHJlZml4OjpoMzIxZTk1YjZlOGQwMDE4YmYvY29yZTo6Zm10Ojpu + dW06OmltcDo6Zm10X3U2NDo6aDRmNGQwOTAwZDJmNmVkZTFnMWNvbXBpbGVyX2J1aWx0aW5zOjptZW06 + Om1lbWNweTo6aDk1MjdhNDgwNmZkYzdhZThoMWNvbXBpbGVyX2J1aWx0aW5zOjptZW06OnN0cmxlbjo6 + aDIwMDE1NTUyZDQ5OGFlMzlpBnN0cmxlbmoGbWVtY3B5AE0JcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVz + dAAMcHJvY2Vzc2VkLWJ5AQVydXN0Yx0xLjc0LjAgKDc5ZTk3MTZjOSAyMDIzLTExLTEzKQAsD3Rhcmdl + dF9mZWF0dXJlcwIrD211dGFibGUtZ2xvYmFscysIc2lnbi1leHQ= diff --git a/testdata/wasmtest/.gitignore b/testdata/wasmtest/.gitignore new file mode 100644 index 0000000..81be965 --- /dev/null +++ b/testdata/wasmtest/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +go_lib.base64 \ No newline at end of file diff --git a/testdata/wasmtest/Cargo.toml b/testdata/wasmtest/Cargo.toml new file mode 100644 index 0000000..f583078 --- /dev/null +++ b/testdata/wasmtest/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "wasmtest" +version = "0.0.1" +authors = ["Dan Kortschak "] +edition = "2018" + +[dependencies] + +# new material +[lib] +crate-type = ["cdylib"] diff --git a/testdata/wasmtest/bundle_lib_obj/main.go b/testdata/wasmtest/bundle_lib_obj/main.go new file mode 100644 index 0000000..285cb83 --- /dev/null +++ b/testdata/wasmtest/bundle_lib_obj/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "flag" + "log" + "os" + + "github.com/goccy/go-yaml" + "golang.org/x/tools/txtar" +) + +type config struct { + Globals map[string]interface{} `yaml:"globals,omitempty"` + Regexps map[string]string `yaml:"regexp,omitempty"` + WASM map[string]wasmModule `yaml:"wasm,omitempty"` + XSDs map[string]string `yaml:"xsd,omitempty"` + Auth map[string]any `yaml:"auth,omitempty"` +} +type wasmModule struct { + Funcs []string `yaml:"funcs,omitempty"` + Environment string `yaml:"env"` + Object string `yaml:"obj"` // base64 encoded bytes +} + +func main() { + tgt := flag.String("test", "", "specify the test file to rewrite") + lib := flag.String("lib", "", "specify the wasm lib to rewrite") + wasm := flag.String("wasm", "", "specify the compiled and base64 encoded wasm object") + flag.Parse() + if *tgt == "" || *lib == "" || *wasm == "" { + flag.Usage() + os.Exit(2) + } + ar, err := txtar.ParseFile(*tgt) + if err != nil { + log.Fatal(err) + } + var ( + i int + f txtar.File + ) + for i, f = range ar.Files { + if f.Name == "cfg.yaml" { + break + } + } + + var cfg config + err = yaml.Unmarshal(f.Data, &cfg) + if err != nil { + log.Fatal(err) + } + + obj := cfg.WASM[*lib] + b, err := os.ReadFile(*wasm) + if err != nil { + log.Fatal(err) + } + obj.Object = string(b) + cfg.WASM[*lib] = obj + b, err = yaml.Marshal(cfg) + if err != nil { + log.Fatal(err) + } + ar.Files[i].Data = b + err = os.WriteFile(*tgt, txtar.Format(ar), 0o664) + if err != nil { + log.Fatal(err) + } +} diff --git a/testdata/wasmtest/lib.go b/testdata/wasmtest/lib.go new file mode 100644 index 0000000..39349d3 --- /dev/null +++ b/testdata/wasmtest/lib.go @@ -0,0 +1,102 @@ +//go:generate tinygo build -o go_lib.wasm -target=wasi lib.go +//go:generate gzip go_lib.wasm +//go:generate bash -c "base64 < go_lib.wasm.gz | fold > go_lib.base64" +//go:generate rm go_lib.wasm.gz +//go:generate go run ./bundle_lib_obj/main.go -test ../wasm.txt -lib go_testmod -wasm go_lib.base64 + +package main + +import "C" + +import ( + "strings" + "unsafe" +) + +func main() {} + +var allocs = map[uintptr][]byte{ + zero: nil, +} + +var zero uintptr + +//export allocate +func allocate(n uintptr) uintptr { + if n == 0 { + return zero + } + m := make([]byte, n) + p := uintptr(unsafe.Pointer(unsafe.SliceData(m))) + allocs[p] = m + return p +} + +//export deallocate +func deallocate(p, _ uintptr) { + if p != zero { + if _, ok := allocs[p]; !ok { + panic("invalid free address") + } + delete(allocs, p) + } +} + +//export sum +func sum(x, y int64) int64 { + return x + y +} + +//export add_one +func addOne(x int64) int64 { + return x + 1 +} + +//export concat_c_string +func concat(a, b *C.char) *C.char { + // Use our own cString function to hook into our allocator rather + // than using the Cgo malloc, but use C.GoString to save work since + // the runtime already has null finding code and allocates with mallocgc. + return cString(C.GoString(a) + C.GoString(b)) +} + +//export concat_bytes +func concatBytes(a, b []byte) []byte { + return append(a[:len(a):len(a)], b...) +} + +//export concat_go_string +func concatGoString(a, b string) string { + return a + b +} + +//export bool_list +func boolList(a, b, c, d, e, f, g, h bool) []bool { + return []bool{a, b, c, d, e, f, g, h} +} + +//export double_list +func doubleList(a, b float64) []float64 { + return []float64{a, b} +} + +//export int_list +func intList(a, b int64) []int64 { + return []int64{a, b} +} + +//export comma_split +func commaSplit(s string) []string { + return strings.Split(s, ",") +} + +func cString(s string) *C.char { + p := allocate(uintptr(len(s) + 1)) + if p == zero { + return nil + } + m := allocs[p] + copy(m, s) + m[len(m)-1] = 0 + return (*C.char)(unsafe.Pointer(unsafe.SliceData(m))) +} diff --git a/testdata/wasmtest/src/lib.rs b/testdata/wasmtest/src/lib.rs new file mode 100644 index 0000000..6b2cca2 --- /dev/null +++ b/testdata/wasmtest/src/lib.rs @@ -0,0 +1,36 @@ +use std::ffi::{CStr, CString}; +use std::mem; +use std::os::raw::{c_char, c_void}; + +#[no_mangle] +pub extern "C" fn add_one(x: i64) -> i64 { + x + 1 +} + +#[no_mangle] +pub extern "C" fn sum(x: i64, y: i64) -> i64 { + x + y +} + +#[no_mangle] +pub extern "C" fn allocate(size: usize) -> *mut c_void { + let mut buffer = Vec::with_capacity(size); + let pointer = buffer.as_mut_ptr(); + mem::forget(buffer); + + pointer as *mut c_void +} + +#[no_mangle] +pub extern "C" fn deallocate(pointer: *mut c_void, capacity: usize) { + unsafe { + let _ = Vec::from_raw_parts(pointer, 0, capacity); + } +} + +#[no_mangle] +pub extern "C" fn concat(a: *mut c_char, b: *mut c_char) -> *mut c_char { + let a = unsafe { CStr::from_ptr(a).to_bytes().to_vec() }; + let b = unsafe { CStr::from_ptr(b).to_bytes().to_vec() }; + unsafe { CString::from_vec_unchecked([a, b].concat().to_vec()) }.into_raw() +} diff --git a/testdata/wasmtest/target/wasm32-unknown-unknown/release/wasmtest.wasm b/testdata/wasmtest/target/wasm32-unknown-unknown/release/wasmtest.wasm new file mode 100755 index 0000000..bb29a6a Binary files /dev/null and b/testdata/wasmtest/target/wasm32-unknown-unknown/release/wasmtest.wasm differ