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>
82 lines
2.7 KiB
Go
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))
|
|
}
|
|
}
|