...
1 package wazero
2
3 import (
4 "context"
5 "errors"
6 "fmt"
7 "os"
8 "path"
9 "path/filepath"
10 goruntime "runtime"
11 "sync"
12
13 "github.com/tetratelabs/wazero/api"
14 "github.com/tetratelabs/wazero/internal/filecache"
15 "github.com/tetratelabs/wazero/internal/version"
16 "github.com/tetratelabs/wazero/internal/wasm"
17 )
18
19
20
21
22
23
24
25
26
27 type CompilationCache interface{ api.Closer }
28
29
30
31
32
33 func NewCompilationCache() CompilationCache {
34 return &cache{}
35 }
36
37
38
39
40
41
42
43
44
45
46
47
48
49 func NewCompilationCacheWithDir(dirname string) (CompilationCache, error) {
50 c := &cache{}
51 err := c.ensuresFileCache(dirname, version.GetWazeroVersion())
52 return c, err
53 }
54
55
56 type cache struct {
57
58
59 engs [engineKindCount]wasm.Engine
60 fileCache filecache.Cache
61 initOnces [engineKindCount]sync.Once
62 }
63
64 func (c *cache) initEngine(ek engineKind, ne newEngine, ctx context.Context, features api.CoreFeatures) wasm.Engine {
65 c.initOnces[ek].Do(func() { c.engs[ek] = ne(ctx, features, c.fileCache) })
66 return c.engs[ek]
67 }
68
69
70 func (c *cache) Close(_ context.Context) (err error) {
71 for _, eng := range c.engs {
72 if eng != nil {
73 if err = eng.Close(); err != nil {
74 return
75 }
76 }
77 }
78 return
79 }
80
81 func (c *cache) ensuresFileCache(dir string, wazeroVersion string) error {
82
83 var err error
84 dir, err = filepath.Abs(dir)
85 if err != nil {
86 return err
87 }
88
89
90 if err = mkdir(dir); err != nil {
91 return err
92 }
93
94
95 dirname := path.Join(dir, "wazero-"+wazeroVersion+"-"+goruntime.GOARCH+"-"+goruntime.GOOS)
96 if err = mkdir(dirname); err != nil {
97 return err
98 }
99
100 c.fileCache = filecache.New(dirname)
101 return nil
102 }
103
104 func mkdir(dirname string) error {
105 if st, err := os.Stat(dirname); errors.Is(err, os.ErrNotExist) {
106
107 if err = os.MkdirAll(dirname, 0o700); err != nil {
108 return fmt.Errorf("create directory %s: %v", dirname, err)
109 }
110 } else if err != nil {
111 return err
112 } else if !st.IsDir() {
113 return fmt.Errorf("%s is not dir", dirname)
114 }
115 return nil
116 }
117
View as plain text