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}