wa_init_api.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package openngvfs
  2. import (
  3. "context"
  4. "fmt"
  5. "git.swzry.com/ProjectNagae/FsUtils/amntfs"
  6. "git.swzry.com/zry/GoHiedaLogger/hiedalog"
  7. "git.swzry.com/zry/go-int32-handle"
  8. "github.com/spf13/afero"
  9. "github.com/tetratelabs/wazero"
  10. wa_api "github.com/tetratelabs/wazero/api"
  11. "os"
  12. )
  13. const API_VERSION_MAJOR = 1
  14. const API_VERSION_MINOR = 1
  15. const API_VERSION_PATCH = 0
  16. type AferoFsInstance struct {
  17. Fs afero.Fs
  18. TypeDescription string
  19. }
  20. type InitWAVMHostAPI struct {
  21. Root *amntfs.AMNTFS
  22. AferoFsInstancesMgr *go_int32_handle.HandleManager[*AferoFsInstance]
  23. }
  24. func NewWAVMHostAPI(root *amntfs.AMNTFS) *InitWAVMHostAPI {
  25. return &InitWAVMHostAPI{
  26. Root: root,
  27. AferoFsInstancesMgr: go_int32_handle.New[*AferoFsInstance](),
  28. }
  29. }
  30. type InitWAVMHostModuleAdapter struct {
  31. api *InitWAVMHostAPI
  32. builder wazero.HostModuleBuilder
  33. rawFsTab *RawFsTab
  34. processedFsTab *ProcessedFsTab
  35. logger *hiedalog.HiedaLogger
  36. }
  37. func NewInitWAVMHostModuleAdapter(builder wazero.HostModuleBuilder, api *InitWAVMHostAPI, fstab *RawFsTab, logger *hiedalog.HiedaLogger, appName string) *InitWAVMHostModuleAdapter {
  38. localKV := make(map[string]string)
  39. for k, v := range fstab.ExKV.Default {
  40. localKV[k] = v
  41. }
  42. appKV, ok := fstab.ExKV.App[appName]
  43. if ok {
  44. for k, v := range appKV {
  45. localKV[k] = v
  46. }
  47. }
  48. processedFsTab := &ProcessedFsTab{
  49. ExKV: localKV,
  50. }
  51. return &InitWAVMHostModuleAdapter{
  52. api: api,
  53. builder: builder,
  54. rawFsTab: fstab,
  55. processedFsTab: processedFsTab,
  56. logger: logger,
  57. }
  58. }
  59. func (a *InitWAVMHostModuleAdapter) addFunc(
  60. name string, f func(ctx context.Context, mod wa_api.Module, params []uint64),
  61. param []wa_api.ValueType, result []wa_api.ValueType,
  62. ) {
  63. a.builder = a.builder.NewFunctionBuilder().
  64. WithGoModuleFunction(wa_api.GoModuleFunc(f), param, result).Export(name)
  65. }
  66. func (a *InitWAVMHostModuleAdapter) Instantiate(ctx context.Context) (wa_api.Module, error) {
  67. a.addFunc("api_ver_get", a.efnApiVerGet,
  68. []wa_api.ValueType{
  69. wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
  70. }, []wa_api.ValueType{})
  71. a.addFunc("exkv_get_len", a.efnExkvGetLen,
  72. []wa_api.ValueType{wa_api.ValueTypeI32, wa_api.ValueTypeI32},
  73. []wa_api.ValueType{wa_api.ValueTypeI32})
  74. a.addFunc("exkv_get_val", a.efnExkvGetVal,
  75. []wa_api.ValueType{
  76. wa_api.ValueTypeI32, wa_api.ValueTypeI32,
  77. wa_api.ValueTypeI32, wa_api.ValueTypeI32,
  78. },
  79. []wa_api.ValueType{wa_api.ValueTypeI32})
  80. a.addFunc("vfs_mount", a.efnVfsMount,
  81. []wa_api.ValueType{
  82. wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
  83. },
  84. []wa_api.ValueType{wa_api.ValueTypeI32})
  85. a.addFunc("vfs_mkdir", a.efnVfsMkdir,
  86. []wa_api.ValueType{
  87. wa_api.ValueTypeI32, wa_api.ValueTypeI32, wa_api.ValueTypeI32,
  88. },
  89. []wa_api.ValueType{wa_api.ValueTypeI32})
  90. a.mfaAddAfs()
  91. return a.builder.Instantiate(ctx)
  92. }
  93. func (a *InitWAVMHostModuleAdapter) efnApiVerGet(_ context.Context, mod wa_api.Module, stack []uint64) {
  94. ptrMaj := uint32(stack[0])
  95. ptrMin := uint32(stack[1])
  96. ptrPat := uint32(stack[2])
  97. mod.Memory().WriteUint32Le(ptrMaj, API_VERSION_MAJOR)
  98. mod.Memory().WriteUint32Le(ptrMin, API_VERSION_MINOR)
  99. mod.Memory().WriteUint32Le(ptrPat, API_VERSION_PATCH)
  100. }
  101. func (a *InitWAVMHostModuleAdapter) efnExkvGetLen(_ context.Context, mod wa_api.Module, stack []uint64) {
  102. ptrKey := uint32(stack[0])
  103. lenKey := uint32(stack[1])
  104. key, ok := mod.Memory().Read(ptrKey, lenKey)
  105. if !ok {
  106. var neg1 int32 = -1
  107. stack[0] = uint64(neg1)
  108. return
  109. }
  110. v, ok := a.processedFsTab.ExKV[string(key)]
  111. if !ok {
  112. var neg2 int32 = -2
  113. stack[0] = uint64(neg2)
  114. } else {
  115. stack[0] = uint64(len([]byte(v)))
  116. }
  117. }
  118. func (a *InitWAVMHostModuleAdapter) efnExkvGetVal(_ context.Context, mod wa_api.Module, stack []uint64) {
  119. ptrKey := uint32(stack[0])
  120. lenKey := uint32(stack[1])
  121. ptrBuf := uint32(stack[2])
  122. lenBuf := uint32(stack[3])
  123. if lenBuf <= 0 {
  124. stack[0] = 0
  125. return
  126. }
  127. key, ok := mod.Memory().Read(ptrKey, lenKey)
  128. if !ok {
  129. var neg1 int32 = -1
  130. stack[0] = uint64(neg1)
  131. return
  132. }
  133. v, ok := a.processedFsTab.ExKV[string(key)]
  134. if !ok {
  135. var neg2 int32 = -2
  136. stack[0] = uint64(neg2)
  137. return
  138. }
  139. vb := []byte(v)
  140. ok = mod.Memory().Write(ptrBuf, vb[:lenBuf])
  141. if !ok {
  142. var neg3 int32 = -3
  143. stack[0] = uint64(neg3)
  144. return
  145. }
  146. stack[0] = uint64(lenBuf)
  147. return
  148. }
  149. func (a *InitWAVMHostModuleAdapter) efnVfsMount(_ context.Context, mod wa_api.Module, stack []uint64) {
  150. hAfs := int32(stack[0])
  151. ptrMntPath := uint32(stack[1])
  152. lenMntPath := uint32(stack[2])
  153. mntPath, ok := mod.Memory().Read(ptrMntPath, lenMntPath)
  154. if !ok {
  155. var neg2 int32 = -2
  156. stack[0] = uint64(neg2)
  157. return
  158. }
  159. if hAfs <= 0 {
  160. var neg1 int32 = -1
  161. stack[0] = uint64(neg1)
  162. return
  163. }
  164. objAfs, ok := a.api.AferoFsInstancesMgr.Get(hAfs)
  165. if !ok {
  166. var neg1 int32 = -1
  167. stack[0] = uint64(neg1)
  168. return
  169. }
  170. err := a.api.Root.Mount(string(mntPath), objAfs.Fs, false)
  171. if err != nil {
  172. if aErr, ok := err.(*amntfs.AMNTFSError); ok {
  173. rawErr := aErr.GetRawError()
  174. var rawErrStr string
  175. if rawErr != nil {
  176. rawErrStr = rawErr.Error()
  177. } else {
  178. rawErrStr = ""
  179. }
  180. if aErr.GetErrNo() == amntfs.ErrMountPointAlreadyMounted {
  181. a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
  182. "type": "mount_error",
  183. "sub-type": "mount_point_already_mounted",
  184. "mnt-point": string(mntPath),
  185. "afs-name": objAfs.Fs.Name(),
  186. "afs-type-desc": objAfs.TypeDescription,
  187. })
  188. var neg3 int32 = -3
  189. stack[0] = uint64(neg3)
  190. return
  191. } else {
  192. a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
  193. "type": "mount_error",
  194. "sub-type": "internal_error",
  195. "mnt-point": string(mntPath),
  196. "afs-name": objAfs.Fs.Name(),
  197. "afs-type-desc": objAfs.TypeDescription,
  198. "raw-err": rawErrStr,
  199. })
  200. var neg4 int32 = -4
  201. stack[0] = uint64(neg4)
  202. return
  203. }
  204. } else {
  205. a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
  206. "type": "mount_error",
  207. "sub-type": "internal_error",
  208. "mnt-point": string(mntPath),
  209. "afs-name": objAfs.Fs.Name(),
  210. "afs-type-desc": objAfs.TypeDescription,
  211. "raw-err": err.Error(),
  212. })
  213. var neg4 int32 = -4
  214. stack[0] = uint64(neg4)
  215. return
  216. }
  217. }
  218. a.logger.LogComplex("ngvfs", hiedalog.DLN_VERBOSE, map[string]string{
  219. "type": "mount_ok",
  220. "mnt-point": string(mntPath),
  221. "afs-name": objAfs.Fs.Name(),
  222. "afs-type-desc": objAfs.TypeDescription,
  223. })
  224. stack[0] = 0
  225. return
  226. }
  227. func (a *InitWAVMHostModuleAdapter) efnVfsMkdir(_ context.Context, mod wa_api.Module, stack []uint64) {
  228. ptrPath := uint32(stack[0])
  229. lenPath := uint32(stack[1])
  230. perm := uint32(stack[2])
  231. dirPath, ok := mod.Memory().Read(ptrPath, lenPath)
  232. if !ok {
  233. var neg2 int32 = -1
  234. stack[0] = uint64(neg2)
  235. return
  236. }
  237. err := a.api.Root.MkdirAll(string(dirPath), os.FileMode(perm))
  238. if err != nil {
  239. a.logger.LogComplex("ngvfs", hiedalog.DLN_WARN, map[string]string{
  240. "type": "vfs_mkdir_error",
  241. "dir-path": string(dirPath),
  242. "perm": fmt.Sprintf("%04o", perm),
  243. "raw-err": err.Error(),
  244. })
  245. var ecode int32 = -2
  246. stack[0] = uint64(ecode)
  247. return
  248. }
  249. a.logger.LogComplex("ngvfs", hiedalog.DLN_VERBOSE, map[string]string{
  250. "type": "vfs_mkdir_ok",
  251. "path": string(dirPath),
  252. })
  253. stack[0] = 0
  254. return
  255. }