123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package openngvfs
- import (
- "context"
- "fmt"
- "git.swzry.com/ProjectNagae/FsUtils/amntfs"
- "git.swzry.com/zry/GoHiedaLogger/hiedalog"
- "git.swzry.com/zry/go-int32-handle"
- "github.com/spf13/afero"
- "github.com/tetratelabs/wazero"
- wa_api "github.com/tetratelabs/wazero/api"
- "os"
- )
- const API_VERSION_MAJOR = 1
- const API_VERSION_MINOR = 1
- const API_VERSION_PATCH = 0
- type AferoFsInstance struct {
- Fs afero.Fs
- TypeDescription string
- }
- type InitWAVMHostAPI struct {
- Root *amntfs.AMNTFS
- AferoFsInstancesMgr *go_int32_handle.HandleManager[*AferoFsInstance]
- }
- func NewWAVMHostAPI(root *amntfs.AMNTFS) *InitWAVMHostAPI {
- return &InitWAVMHostAPI{
- Root: root,
- AferoFsInstancesMgr: go_int32_handle.New[*AferoFsInstance](),
- }
- }
- type InitWAVMHostModuleAdapter struct {
- api *InitWAVMHostAPI
- builder wazero.HostModuleBuilder
- rawFsTab *RawFsTab
- processedFsTab *ProcessedFsTab
- logger *hiedalog.HiedaLogger
- }
- func NewInitWAVMHostModuleAdapter(builder wazero.HostModuleBuilder, api *InitWAVMHostAPI, fstab *RawFsTab, logger *hiedalog.HiedaLogger, appName string) *InitWAVMHostModuleAdapter {
- localKV := make(map[string]string)
- for k, v := range fstab.ExKV.Default {
- localKV[k] = v
- }
- appKV, ok := fstab.ExKV.App[appName]
- if ok {
- for k, v := range appKV {
- localKV[k] = v
- }
- }
- processedFsTab := &ProcessedFsTab{
- ExKV: localKV,
- }
- return &InitWAVMHostModuleAdapter{
- api: api,
- builder: builder,
- rawFsTab: fstab,
- processedFsTab: processedFsTab,
- logger: logger,
- }
- }
- func (a *InitWAVMHostModuleAdapter) addFunc(
- name string, f func(ctx context.Context, mod wa_api.Module, params []uint64),
- param []wa_api.ValueType, result []wa_api.ValueType,
- ) {
- a.builder = a.builder.NewFunctionBuilder().
- WithGoModuleFunction(wa_api.GoModuleFunc(f), param, result).Export(name)
- }
- func (a *InitWAVMHostModuleAdapter) Instantiate(ctx context.Context) (wa_api.Module, error) {
- a.addFunc("api_ver_get", a.efnApiVerGet,
- []wa_api.ValueType{
- wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
- }, []wa_api.ValueType{})
- a.addFunc("exkv_get_len", a.efnExkvGetLen,
- []wa_api.ValueType{wa_api.ValueTypeI32, wa_api.ValueTypeI32},
- []wa_api.ValueType{wa_api.ValueTypeI32})
- a.addFunc("exkv_get_val", a.efnExkvGetVal,
- []wa_api.ValueType{
- wa_api.ValueTypeI32, wa_api.ValueTypeI32,
- wa_api.ValueTypeI32, wa_api.ValueTypeI32,
- },
- []wa_api.ValueType{wa_api.ValueTypeI32})
- a.addFunc("vfs_mount", a.efnVfsMount,
- []wa_api.ValueType{
- wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
- },
- []wa_api.ValueType{wa_api.ValueTypeI32})
- a.addFunc("vfs_mkdir", a.efnVfsMkdir,
- []wa_api.ValueType{
- wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
- },
- []wa_api.ValueType{wa_api.ValueTypeI32})
- a.mfaAddAfs()
- return a.builder.Instantiate(ctx)
- }
- func (a *InitWAVMHostModuleAdapter) efnApiVerGet(_ context.Context, mod wa_api.Module, stack []uint64) {
- ptrMaj := uint32(stack[0])
- ptrMin := uint32(stack[1])
- ptrPat := uint32(stack[2])
- mod.Memory().WriteUint32Le(ptrMaj, API_VERSION_MAJOR)
- mod.Memory().WriteUint32Le(ptrMin, API_VERSION_MINOR)
- mod.Memory().WriteUint32Le(ptrPat, API_VERSION_PATCH)
- }
- func (a *InitWAVMHostModuleAdapter) efnExkvGetLen(_ context.Context, mod wa_api.Module, stack []uint64) {
- ptrKey := uint32(stack[0])
- lenKey := uint32(stack[1])
- key, ok := mod.Memory().Read(ptrKey, lenKey)
- if !ok {
- var neg1 int32 = -1
- stack[0] = uint64(neg1)
- return
- }
- v, ok := a.processedFsTab.ExKV[string(key)]
- if !ok {
- var neg2 int32 = -2
- stack[0] = uint64(neg2)
- } else {
- stack[0] = uint64(len([]byte(v)))
- }
- }
- func (a *InitWAVMHostModuleAdapter) efnExkvGetVal(_ context.Context, mod wa_api.Module, stack []uint64) {
- ptrKey := uint32(stack[0])
- lenKey := uint32(stack[1])
- ptrBuf := uint32(stack[2])
- lenBuf := uint32(stack[3])
- if lenBuf <= 0 {
- stack[0] = 0
- return
- }
- key, ok := mod.Memory().Read(ptrKey, lenKey)
- if !ok {
- var neg1 int32 = -1
- stack[0] = uint64(neg1)
- return
- }
- v, ok := a.processedFsTab.ExKV[string(key)]
- if !ok {
- var neg2 int32 = -2
- stack[0] = uint64(neg2)
- return
- }
- vb := []byte(v)
- ok = mod.Memory().Write(ptrBuf, vb[:lenBuf])
- if !ok {
- var neg3 int32 = -3
- stack[0] = uint64(neg3)
- return
- }
- stack[0] = uint64(lenBuf)
- return
- }
- func (a *InitWAVMHostModuleAdapter) efnVfsMount(_ context.Context, mod wa_api.Module, stack []uint64) {
- hAfs := int32(stack[0])
- ptrMntPath := uint32(stack[1])
- lenMntPath := uint32(stack[2])
- mntPath, ok := mod.Memory().Read(ptrMntPath, lenMntPath)
- if !ok {
- var neg2 int32 = -2
- stack[0] = uint64(neg2)
- return
- }
- if hAfs <= 0 {
- var neg1 int32 = -1
- stack[0] = uint64(neg1)
- return
- }
- objAfs, ok := a.api.AferoFsInstancesMgr.Get(hAfs)
- if !ok {
- var neg1 int32 = -1
- stack[0] = uint64(neg1)
- return
- }
- err := a.api.Root.Mount(string(mntPath), objAfs.Fs, false)
- if err != nil {
- if aErr, ok := err.(*amntfs.AMNTFSError); ok {
- rawErr := aErr.GetRawError()
- var rawErrStr string
- if rawErr != nil {
- rawErrStr = rawErr.Error()
- } else {
- rawErrStr = ""
- }
- if aErr.GetErrNo() == amntfs.ErrMountPointAlreadyMounted {
- a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
- "type": "mount_error",
- "sub-type": "mount_point_already_mounted",
- "mnt-point": string(mntPath),
- "afs-name": objAfs.Fs.Name(),
- "afs-type-desc": objAfs.TypeDescription,
- })
- var neg3 int32 = -3
- stack[0] = uint64(neg3)
- return
- } else {
- a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
- "type": "mount_error",
- "sub-type": "internal_error",
- "mnt-point": string(mntPath),
- "afs-name": objAfs.Fs.Name(),
- "afs-type-desc": objAfs.TypeDescription,
- "raw-err": rawErrStr,
- })
- var neg4 int32 = -4
- stack[0] = uint64(neg4)
- return
- }
- } else {
- a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
- "type": "mount_error",
- "sub-type": "internal_error",
- "mnt-point": string(mntPath),
- "afs-name": objAfs.Fs.Name(),
- "afs-type-desc": objAfs.TypeDescription,
- "raw-err": err.Error(),
- })
- var neg4 int32 = -4
- stack[0] = uint64(neg4)
- return
- }
- }
- a.logger.LogComplex("ngvfs", hiedalog.DLN_VERBOSE, map[string]string{
- "type": "mount_ok",
- "mnt-point": string(mntPath),
- "afs-name": objAfs.Fs.Name(),
- "afs-type-desc": objAfs.TypeDescription,
- })
- stack[0] = 0
- return
- }
- func (a *InitWAVMHostModuleAdapter) efnVfsMkdir(_ context.Context, mod wa_api.Module, stack []uint64) {
- ptrPath := uint32(stack[0])
- lenPath := uint32(stack[1])
- perm := uint32(stack[2])
- dirPath, ok := mod.Memory().Read(ptrPath, lenPath)
- if !ok {
- var neg2 int32 = -1
- stack[0] = uint64(neg2)
- return
- }
- err := a.api.Root.MkdirAll(string(dirPath), os.FileMode(perm))
- if err != nil {
- a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
- "type": "vfs_mkdir_error",
- "dir-path": string(dirPath),
- "perm": fmt.Sprintf("%04o", perm),
- "raw-err": err.Error(),
- })
- var ecode int32 = -2
- stack[0] = uint64(ecode)
- return
- }
- a.logger.LogComplex("ngvfs", hiedalog.DLN_VERBOSE, map[string]string{
- "type": "vfs_mkdir_ok",
- "path": string(dirPath),
- })
- stack[0] = 0
- return
- }
|