Files
wazero/internal/wasm/counts.go
Crypt Keeper c68d16e61c Adds import count functions to unlock shared text decoding (#299)
Right now, it is a lot of copy/paste to decode inlined import
abbreviation with the same parser as module-defined ones. The primary
reason for this is that the import section is only guaranteed before
module-defined *after* expanding abbreviations. For example,

`(func (import "foo" "bar") ...` follows imports and may be followed by
any number of abbreviations. This means you can't know the end of
imports until you see the first `(func` which doesn't abbreviate one.

While certain external types, namely memory and table, can only be
imported once, this also applies to globals.

This change makes counting the current imports a `func() uint32` so that
it can be decoupled and used for any external type. Other PRs can
simplify memory and table which can only be imported once, but the
general signatures here will still work.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-02-28 15:15:14 +09:00

82 lines
2.7 KiB
Go

package internalwasm
import "fmt"
// ImportFuncCount returns the possibly empty count of imported functions. This plus SectionElementCount of
// SectionIDFunction is the size of the function index namespace.
func (m *Module) ImportFuncCount() uint32 {
return m.importCount(ExternTypeFunc)
}
// ImportTableCount returns the possibly empty count of imported tables. This plus SectionElementCount of SectionIDTable
// is the size of the table index namespace.
func (m *Module) ImportTableCount() uint32 {
return m.importCount(ExternTypeTable) // TODO: once validation happens on decode, this is zero or one.
}
// ImportMemoryCount returns the possibly empty count of imported memories. This plus SectionElementCount of
// SectionIDMemory is the size of the memory index namespace.
func (m *Module) ImportMemoryCount() uint32 {
return m.importCount(ExternTypeMemory) // TODO: once validation happens on decode, this is zero or one.
}
// ImportGlobalCount returns the possibly empty count of imported globals. This plus SectionElementCount of
// SectionIDGlobal is the size of the global index namespace.
func (m *Module) ImportGlobalCount() uint32 {
return m.importCount(ExternTypeGlobal)
}
// importCount returns the count of a specific type of import. This is important because it is easy to mistake the
// length of the import section with the count of a specific kind of import.
func (m *Module) importCount(et ExternType) (res uint32) {
for _, im := range m.ImportSection {
if im.Type == et {
res++
}
}
return
}
// SectionElementCount returns the count of elements in a given section ID
//
// For example...
// * SectionIDType returns the count of FunctionType
// * SectionIDCustom returns one if the NameSection is present
// * SectionIDExport returns the count of unique export names
func (m *Module) SectionElementCount(sectionID SectionID) uint32 { // element as in vector elements!
switch sectionID {
case SectionIDCustom:
if m.NameSection != nil {
return 1
}
return 0
case SectionIDType:
return uint32(len(m.TypeSection))
case SectionIDImport:
return uint32(len(m.ImportSection))
case SectionIDFunction:
return uint32(len(m.FunctionSection))
case SectionIDTable:
return uint32(len(m.TableSection))
case SectionIDMemory:
return uint32(len(m.MemorySection))
case SectionIDGlobal:
return uint32(len(m.GlobalSection))
case SectionIDExport:
return uint32(len(m.ExportSection))
case SectionIDStart:
if m.StartSection != nil {
return 1
}
return 0
case SectionIDElement:
return uint32(len(m.ElementSection))
case SectionIDCode:
return uint32(len(m.CodeSection))
case SectionIDData:
return uint32(len(m.DataSection))
default:
panic(fmt.Errorf("BUG: unknown section: %d", sectionID))
}
}