memory_definition.go

  1package wasm
  2
  3import (
  4	"github.com/tetratelabs/wazero/api"
  5	"github.com/tetratelabs/wazero/internal/internalapi"
  6)
  7
  8// ImportedMemories implements the same method as documented on wazero.CompiledModule.
  9func (m *Module) ImportedMemories() (ret []api.MemoryDefinition) {
 10	for i := range m.MemoryDefinitionSection {
 11		d := &m.MemoryDefinitionSection[i]
 12		if d.importDesc != nil {
 13			ret = append(ret, d)
 14		}
 15	}
 16	return
 17}
 18
 19// ExportedMemories implements the same method as documented on wazero.CompiledModule.
 20func (m *Module) ExportedMemories() map[string]api.MemoryDefinition {
 21	ret := map[string]api.MemoryDefinition{}
 22	for i := range m.MemoryDefinitionSection {
 23		d := &m.MemoryDefinitionSection[i]
 24		for _, e := range d.exportNames {
 25			ret[e] = d
 26		}
 27	}
 28	return ret
 29}
 30
 31// BuildMemoryDefinitions generates memory metadata that can be parsed from
 32// the module. This must be called after all validation.
 33//
 34// Note: This is exported for wazero.Runtime `CompileModule`.
 35func (m *Module) BuildMemoryDefinitions() {
 36	var moduleName string
 37	if m.NameSection != nil {
 38		moduleName = m.NameSection.ModuleName
 39	}
 40
 41	memoryCount := m.ImportMemoryCount
 42	if m.MemorySection != nil {
 43		memoryCount++
 44	}
 45
 46	if memoryCount == 0 {
 47		return
 48	}
 49
 50	m.MemoryDefinitionSection = make([]MemoryDefinition, 0, memoryCount)
 51	importMemIdx := Index(0)
 52	for i := range m.ImportSection {
 53		imp := &m.ImportSection[i]
 54		if imp.Type != ExternTypeMemory {
 55			continue
 56		}
 57
 58		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, MemoryDefinition{
 59			importDesc: &[2]string{imp.Module, imp.Name},
 60			index:      importMemIdx,
 61			memory:     imp.DescMem,
 62		})
 63		importMemIdx++
 64	}
 65
 66	if m.MemorySection != nil {
 67		m.MemoryDefinitionSection = append(m.MemoryDefinitionSection, MemoryDefinition{
 68			index:  importMemIdx,
 69			memory: m.MemorySection,
 70		})
 71	}
 72
 73	for i := range m.MemoryDefinitionSection {
 74		d := &m.MemoryDefinitionSection[i]
 75		d.moduleName = moduleName
 76		for i := range m.ExportSection {
 77			e := &m.ExportSection[i]
 78			if e.Type == ExternTypeMemory && e.Index == d.index {
 79				d.exportNames = append(d.exportNames, e.Name)
 80			}
 81		}
 82	}
 83}
 84
 85// MemoryDefinition implements api.MemoryDefinition
 86type MemoryDefinition struct {
 87	internalapi.WazeroOnlyType
 88	moduleName  string
 89	index       Index
 90	importDesc  *[2]string
 91	exportNames []string
 92	memory      *Memory
 93}
 94
 95// ModuleName implements the same method as documented on api.MemoryDefinition.
 96func (f *MemoryDefinition) ModuleName() string {
 97	return f.moduleName
 98}
 99
100// Index implements the same method as documented on api.MemoryDefinition.
101func (f *MemoryDefinition) Index() uint32 {
102	return f.index
103}
104
105// Import implements the same method as documented on api.MemoryDefinition.
106func (f *MemoryDefinition) Import() (moduleName, name string, isImport bool) {
107	if importDesc := f.importDesc; importDesc != nil {
108		moduleName, name, isImport = importDesc[0], importDesc[1], true
109	}
110	return
111}
112
113// ExportNames implements the same method as documented on api.MemoryDefinition.
114func (f *MemoryDefinition) ExportNames() []string {
115	return f.exportNames
116}
117
118// Min implements the same method as documented on api.MemoryDefinition.
119func (f *MemoryDefinition) Min() uint32 {
120	return f.memory.Min
121}
122
123// Max implements the same method as documented on api.MemoryDefinition.
124func (f *MemoryDefinition) Max() (max uint32, encoded bool) {
125	max = f.memory.Max
126	encoded = f.memory.IsMaxEncoded
127	return
128}