github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/wasm/store_module_list.go (about) 1 package wasm 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/tetratelabs/wazero/api" 8 ) 9 10 // deleteModule makes the moduleName available for instantiation again. 11 func (s *Store) deleteModule(m *ModuleInstance) error { 12 s.mux.Lock() 13 defer s.mux.Unlock() 14 15 // Remove this module name. 16 if m.prev != nil { 17 m.prev.next = m.next 18 } 19 if m.next != nil { 20 m.next.prev = m.prev 21 } 22 if s.moduleList == m { 23 s.moduleList = m.next 24 } 25 // Clear the m state so it does not enter any other branch 26 // on subsequent calls to deleteModule. 27 m.prev = nil 28 m.next = nil 29 30 if m.ModuleName != "" { 31 delete(s.nameToModule, m.ModuleName) 32 33 // Shrink the map if it's allocated more than twice the size of the list 34 newCap := len(s.nameToModule) 35 if newCap < nameToModuleShrinkThreshold { 36 newCap = nameToModuleShrinkThreshold 37 } 38 if newCap*2 <= s.nameToModuleCap { 39 nameToModule := make(map[string]*ModuleInstance, newCap) 40 for k, v := range s.nameToModule { 41 nameToModule[k] = v 42 } 43 s.nameToModule = nameToModule 44 s.nameToModuleCap = newCap 45 } 46 } 47 return nil 48 } 49 50 // module returns the module of the given name or error if not in this store 51 func (s *Store) module(moduleName string) (*ModuleInstance, error) { 52 s.mux.RLock() 53 defer s.mux.RUnlock() 54 m, ok := s.nameToModule[moduleName] 55 if !ok { 56 return nil, fmt.Errorf("module[%s] not instantiated", moduleName) 57 } 58 return m, nil 59 } 60 61 // registerModule registers a ModuleInstance into the store. 62 // This makes the ModuleInstance visible for import if it's not anonymous, and ensures it is closed when the store is. 63 func (s *Store) registerModule(m *ModuleInstance) error { 64 s.mux.Lock() 65 defer s.mux.Unlock() 66 67 if s.nameToModule == nil { 68 return errors.New("already closed") 69 } 70 71 if m.ModuleName != "" { 72 if _, ok := s.nameToModule[m.ModuleName]; ok { 73 return fmt.Errorf("module[%s] has already been instantiated", m.ModuleName) 74 } 75 s.nameToModule[m.ModuleName] = m 76 if len(s.nameToModule) > s.nameToModuleCap { 77 s.nameToModuleCap = len(s.nameToModule) 78 } 79 } 80 81 // Add the newest node to the moduleNamesList as the head. 82 m.next = s.moduleList 83 if m.next != nil { 84 m.next.prev = m 85 } 86 s.moduleList = m 87 return nil 88 } 89 90 // Module implements wazero.Runtime Module 91 func (s *Store) Module(moduleName string) api.Module { 92 m, err := s.module(moduleName) 93 if err != nil { 94 return nil 95 } 96 return m 97 }