summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go226
1 files changed, 226 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go
new file mode 100644
index 000000000..622ee5923
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go
@@ -0,0 +1,226 @@
+package binary
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+
+ "github.com/tetratelabs/wazero/api"
+ "github.com/tetratelabs/wazero/internal/leb128"
+ "github.com/tetratelabs/wazero/internal/wasm"
+)
+
+func decodeTypeSection(enabledFeatures api.CoreFeatures, r *bytes.Reader) ([]wasm.FunctionType, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]wasm.FunctionType, vs)
+ for i := uint32(0); i < vs; i++ {
+ if err = decodeFunctionType(enabledFeatures, r, &result[i]); err != nil {
+ return nil, fmt.Errorf("read %d-th type: %v", i, err)
+ }
+ }
+ return result, nil
+}
+
+// decodeImportSection decodes the decoded import segments plus the count per wasm.ExternType.
+func decodeImportSection(
+ r *bytes.Reader,
+ memorySizer memorySizer,
+ memoryLimitPages uint32,
+ enabledFeatures api.CoreFeatures,
+) (result []wasm.Import,
+ perModule map[string][]*wasm.Import,
+ funcCount, globalCount, memoryCount, tableCount wasm.Index, err error,
+) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ err = fmt.Errorf("get size of vector: %w", err)
+ return
+ }
+
+ perModule = make(map[string][]*wasm.Import)
+ result = make([]wasm.Import, vs)
+ for i := uint32(0); i < vs; i++ {
+ imp := &result[i]
+ if err = decodeImport(r, i, memorySizer, memoryLimitPages, enabledFeatures, imp); err != nil {
+ return
+ }
+ switch imp.Type {
+ case wasm.ExternTypeFunc:
+ imp.IndexPerType = funcCount
+ funcCount++
+ case wasm.ExternTypeGlobal:
+ imp.IndexPerType = globalCount
+ globalCount++
+ case wasm.ExternTypeMemory:
+ imp.IndexPerType = memoryCount
+ memoryCount++
+ case wasm.ExternTypeTable:
+ imp.IndexPerType = tableCount
+ tableCount++
+ }
+ perModule[imp.Module] = append(perModule[imp.Module], imp)
+ }
+ return
+}
+
+func decodeFunctionSection(r *bytes.Reader) ([]uint32, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]uint32, vs)
+ for i := uint32(0); i < vs; i++ {
+ if result[i], _, err = leb128.DecodeUint32(r); err != nil {
+ return nil, fmt.Errorf("get type index: %w", err)
+ }
+ }
+ return result, err
+}
+
+func decodeTableSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.Table, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("error reading size")
+ }
+ if vs > 1 {
+ if err := enabledFeatures.RequireEnabled(api.CoreFeatureReferenceTypes); err != nil {
+ return nil, fmt.Errorf("at most one table allowed in module as %w", err)
+ }
+ }
+
+ ret := make([]wasm.Table, vs)
+ for i := range ret {
+ err = decodeTable(r, enabledFeatures, &ret[i])
+ if err != nil {
+ return nil, err
+ }
+ }
+ return ret, nil
+}
+
+func decodeMemorySection(
+ r *bytes.Reader,
+ enabledFeatures api.CoreFeatures,
+ memorySizer memorySizer,
+ memoryLimitPages uint32,
+) (*wasm.Memory, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("error reading size")
+ }
+ if vs > 1 {
+ return nil, fmt.Errorf("at most one memory allowed in module, but read %d", vs)
+ } else if vs == 0 {
+ // memory count can be zero.
+ return nil, nil
+ }
+
+ return decodeMemory(r, enabledFeatures, memorySizer, memoryLimitPages)
+}
+
+func decodeGlobalSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.Global, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]wasm.Global, vs)
+ for i := uint32(0); i < vs; i++ {
+ if err = decodeGlobal(r, enabledFeatures, &result[i]); err != nil {
+ return nil, fmt.Errorf("global[%d]: %w", i, err)
+ }
+ }
+ return result, nil
+}
+
+func decodeExportSection(r *bytes.Reader) ([]wasm.Export, map[string]*wasm.Export, error) {
+ vs, _, sizeErr := leb128.DecodeUint32(r)
+ if sizeErr != nil {
+ return nil, nil, fmt.Errorf("get size of vector: %v", sizeErr)
+ }
+
+ exportMap := make(map[string]*wasm.Export, vs)
+ exportSection := make([]wasm.Export, vs)
+ for i := wasm.Index(0); i < vs; i++ {
+ export := &exportSection[i]
+ err := decodeExport(r, export)
+ if err != nil {
+ return nil, nil, fmt.Errorf("read export: %w", err)
+ }
+ if _, ok := exportMap[export.Name]; ok {
+ return nil, nil, fmt.Errorf("export[%d] duplicates name %q", i, export.Name)
+ } else {
+ exportMap[export.Name] = export
+ }
+ }
+ return exportSection, exportMap, nil
+}
+
+func decodeStartSection(r *bytes.Reader) (*wasm.Index, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get function index: %w", err)
+ }
+ return &vs, nil
+}
+
+func decodeElementSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.ElementSegment, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]wasm.ElementSegment, vs)
+ for i := uint32(0); i < vs; i++ {
+ if err = decodeElementSegment(r, enabledFeatures, &result[i]); err != nil {
+ return nil, fmt.Errorf("read element: %w", err)
+ }
+ }
+ return result, nil
+}
+
+func decodeCodeSection(r *bytes.Reader) ([]wasm.Code, error) {
+ codeSectionStart := uint64(r.Len())
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]wasm.Code, vs)
+ for i := uint32(0); i < vs; i++ {
+ err = decodeCode(r, codeSectionStart, &result[i])
+ if err != nil {
+ return nil, fmt.Errorf("read %d-th code segment: %v", i, err)
+ }
+ }
+ return result, nil
+}
+
+func decodeDataSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.DataSegment, error) {
+ vs, _, err := leb128.DecodeUint32(r)
+ if err != nil {
+ return nil, fmt.Errorf("get size of vector: %w", err)
+ }
+
+ result := make([]wasm.DataSegment, vs)
+ for i := uint32(0); i < vs; i++ {
+ if err = decodeDataSegment(r, enabledFeatures, &result[i]); err != nil {
+ return nil, fmt.Errorf("read data segment: %w", err)
+ }
+ }
+ return result, nil
+}
+
+func decodeDataCountSection(r *bytes.Reader) (count *uint32, err error) {
+ v, _, err := leb128.DecodeUint32(r)
+ if err != nil && err != io.EOF {
+ // data count is optional, so EOF is fine.
+ return nil, err
+ }
+ return &v, nil
+}