Files
wazero/internal/wasm/counts.go
Takeshi Yoneda b63d4e6dcd Deletes namespace API (#1018)
Formerly, we introduced `wazero.Namespace` to help avoid module name or import conflicts while still sharing the runtime's compilation cache. Now that we've introduced `CompilationCache` `wazero.Namespace` is no longer necessary. By removing it, we reduce the conceptual load on end users as well internal complexity. Since most users don't use namespace, the change isn't very impactful.

Users who are only trying to avoid module name conflict can generate a name like below instead of using multiple runtimes:

```go
moduleName := fmt.Sprintf("%d", atomic.AddUint64(&m.instanceCounter, 1))
module, err := runtime.InstantiateModule(ctx, compiled, config.WithName(moduleName))
```

For `HostModuleBuilder` users, we no longer take `Namespace` as the last parameter of `Instantiate` method: 

```diff
 	// log to the console.
 	_, err := r.NewHostModuleBuilder("env").
 		NewFunctionBuilder().WithFunc(logString).Export("log").
-		Instantiate(ctx, r)
+		Instantiate(ctx)
 	if err != nil {
 		log.Panicln(err)
 	}
```


The following is an example diff a use of namespace can use to keep compilation cache while also ensuring their modules don't conflict:

```diff

 func useMultipleRuntimes(ctx context.Context, cache) {
-	r := wazero.NewRuntime(ctx)
+	cache := wazero.NewCompilationCache()
 
 	for i := 0; i < N; i++ {
-		// Create a new namespace to instantiate modules into.
-		ns := r.NewNamespace(ctx) // Note: this is closed when the Runtime is
+		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().WithCompilationCache(cache))
 
 		// Instantiate a new "env" module which exports a stateful function.
 		_, err := r.NewHostModuleBuilder("env").
```

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-10 14:11:46 +09:00

87 lines
2.8 KiB
Go

package wasm
import "fmt"
// ImportFuncCount returns the possibly empty count of imported functions. This plus SectionElementCount of
// SectionIDFunction is the size of the function index.
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.
func (m *Module) ImportTableCount() uint32 {
return m.importCount(ExternTypeTable)
}
// ImportMemoryCount returns the possibly empty count of imported memories. This plus SectionElementCount of
// SectionIDMemory is the size of the memory index.
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.
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 the count of CustomSections plus one if NameSection is present
// * SectionIDHostFunction returns the count of HostFunctionSection
// * SectionIDExport returns the count of unique export names
func (m *Module) SectionElementCount(sectionID SectionID) uint32 { // element as in vector elements!
switch sectionID {
case SectionIDCustom:
numCustomSections := uint32(len(m.CustomSections))
if m.NameSection != nil {
numCustomSections++
}
return numCustomSections
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:
if m.MemorySection != nil {
return 1
}
return 0
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))
}
}