github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/wasm/memory_definition.go (about)

     1  package wasm
     2  
     3  import (
     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.
     9  func (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.
    20  func (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`.
    35  func (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
    86  type 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.
    96  func (f *MemoryDefinition) ModuleName() string {
    97  	return f.moduleName
    98  }
    99  
   100  // Index implements the same method as documented on api.MemoryDefinition.
   101  func (f *MemoryDefinition) Index() uint32 {
   102  	return f.index
   103  }
   104  
   105  // Import implements the same method as documented on api.MemoryDefinition.
   106  func (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.
   114  func (f *MemoryDefinition) ExportNames() []string {
   115  	return f.exportNames
   116  }
   117  
   118  // Min implements the same method as documented on api.MemoryDefinition.
   119  func (f *MemoryDefinition) Min() uint32 {
   120  	return f.memory.Min
   121  }
   122  
   123  // Max implements the same method as documented on api.MemoryDefinition.
   124  func (f *MemoryDefinition) Max() (max uint32, encoded bool) {
   125  	max = f.memory.Max
   126  	encoded = f.memory.IsMaxEncoded
   127  	return
   128  }