We formerly introduced `MemorySizer` as a way to control capacity independently of size. This was the first and only feature in `CompileConfig`. While possibly used privately, `MemorySizer` has never been used in public GitHub code. These APIs interfere with how we do caching of compiled modules. Notably, they can change the min or max defined in wasm, which invalidates some constants. This has also had a bad experience, forcing everyone to boilerplate`wazero.NewCompileConfig()` despite that API never being used in open source. This addresses the use cases in a different way, by moving configuration to `RuntimeConfig` instead. This allows us to remove `MemorySizer` and `CompileConfig`, and the problems with them, yet still retaining functionality in case someone uses it. * `RuntimeConfig.WithMemoryLimitPages(uint32)`: Prevents memory from growing to 4GB (spec limit) per instance. * This works regardless of whether the wasm encodes max or not. If there is no max, it becomes effectively this value. * `RuntimeConfig.WithMemoryCapacityFromMax(bool)`: Prevents reallocations (when growing). * Wasm that never sets max will grow from min to the limit above. Note: Those who want to change their wasm (ex insert a max where there was none), have to do that externally, ex via compiler settings or post-build transformations such as [wabin](https://github.com/tetratelabs/wabin) Signed-off-by: Adrian Cole <adrian@tetrate.io>
82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package binary
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
|
|
"github.com/tetratelabs/wazero/api"
|
|
"github.com/tetratelabs/wazero/internal/leb128"
|
|
"github.com/tetratelabs/wazero/internal/wasm"
|
|
)
|
|
|
|
func decodeImport(
|
|
r *bytes.Reader,
|
|
idx uint32,
|
|
memorySizer func(minPages uint32, maxPages *uint32) (min, capacity, max uint32),
|
|
memoryLimitPages uint32,
|
|
enabledFeatures api.CoreFeatures,
|
|
) (i *wasm.Import, err error) {
|
|
i = &wasm.Import{}
|
|
if i.Module, _, err = decodeUTF8(r, "import module"); err != nil {
|
|
return nil, fmt.Errorf("import[%d] error decoding module: %w", idx, err)
|
|
}
|
|
|
|
if i.Name, _, err = decodeUTF8(r, "import name"); err != nil {
|
|
return nil, fmt.Errorf("import[%d] error decoding name: %w", idx, err)
|
|
}
|
|
|
|
b, err := r.ReadByte()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("import[%d] error decoding type: %w", idx, err)
|
|
}
|
|
i.Type = b
|
|
switch i.Type {
|
|
case wasm.ExternTypeFunc:
|
|
i.DescFunc, _, err = leb128.DecodeUint32(r)
|
|
case wasm.ExternTypeTable:
|
|
i.DescTable, err = decodeTable(r, enabledFeatures)
|
|
case wasm.ExternTypeMemory:
|
|
i.DescMem, err = decodeMemory(r, memorySizer, memoryLimitPages)
|
|
case wasm.ExternTypeGlobal:
|
|
i.DescGlobal, err = decodeGlobalType(r)
|
|
default:
|
|
err = fmt.Errorf("%w: invalid byte for importdesc: %#x", ErrInvalidByte, b)
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("import[%d] %s[%s.%s]: %w", idx, wasm.ExternTypeName(i.Type), i.Module, i.Name, err)
|
|
}
|
|
return
|
|
}
|
|
|
|
// encodeImport returns the wasm.Import encoded in WebAssembly 1.0 (20191205) Binary Format.
|
|
//
|
|
// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-import
|
|
func encodeImport(i *wasm.Import) []byte {
|
|
data := encodeSizePrefixed([]byte(i.Module))
|
|
data = append(data, encodeSizePrefixed([]byte(i.Name))...)
|
|
data = append(data, i.Type)
|
|
switch i.Type {
|
|
case wasm.ExternTypeFunc:
|
|
data = append(data, leb128.EncodeUint32(i.DescFunc)...)
|
|
case wasm.ExternTypeTable:
|
|
data = append(data, wasm.RefTypeFuncref)
|
|
data = append(data, encodeLimitsType(i.DescTable.Min, i.DescTable.Max)...)
|
|
case wasm.ExternTypeMemory:
|
|
maxPtr := &i.DescMem.Max
|
|
if !i.DescMem.IsMaxEncoded {
|
|
maxPtr = nil
|
|
}
|
|
data = append(data, encodeLimitsType(i.DescMem.Min, maxPtr)...)
|
|
case wasm.ExternTypeGlobal:
|
|
g := i.DescGlobal
|
|
var mutable byte
|
|
if g.Mutable {
|
|
mutable = 1
|
|
}
|
|
data = append(data, g.ValType, mutable)
|
|
default:
|
|
panic(fmt.Errorf("invalid externtype: %s", wasm.ExternTypeName(i.Type)))
|
|
}
|
|
return data
|
|
}
|