diff options
author | 2024-05-27 15:46:15 +0000 | |
---|---|---|
committer | 2024-05-27 17:46:15 +0200 | |
commit | 1e7b32490dfdccddd04f46d4b0416b48d749d51b (patch) | |
tree | 62a11365933a5a11e0800af64cbdf9172e5e6e7a /vendor/github.com/tetratelabs/wazero/internal/wasm/binary/section.go | |
parent | [chore] Small styling + link issues (#2933) (diff) | |
download | gotosocial-1e7b32490dfdccddd04f46d4b0416b48d749d51b.tar.xz |
[experiment] add alternative wasm sqlite3 implementation available via build-tag (#2863)
This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
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.go | 226 |
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 +} |