diff --git a/go.mod b/go.mod index 8ea13ead0..60198a7fd 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( codeberg.org/gruf/go-debug v1.3.0 codeberg.org/gruf/go-errors/v2 v2.3.2 codeberg.org/gruf/go-fastcopy v1.1.3 - codeberg.org/gruf/go-ffmpreg v0.2.6 + codeberg.org/gruf/go-ffmpreg v0.3.1 codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf codeberg.org/gruf/go-kv v1.6.5 codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f @@ -55,7 +55,7 @@ require ( github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8 github.com/tdewolff/minify/v2 v2.20.37 github.com/technologize/otel-go-contrib v1.1.1 - github.com/tetratelabs/wazero v1.8.0 + github.com/tetratelabs/wazero v1.8.1 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/ulule/limiter/v3 v3.11.2 github.com/uptrace/bun v1.2.1 diff --git a/go.sum b/go.sum index ab0892565..06b946bc6 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ codeberg.org/gruf/go-fastcopy v1.1.3 h1:Jo9VTQjI6KYimlw25PPc7YLA3Xm+XMQhaHwKnM7x codeberg.org/gruf/go-fastcopy v1.1.3/go.mod h1:GDDYR0Cnb3U/AIfGM3983V/L+GN+vuwVMvrmVABo21s= codeberg.org/gruf/go-fastpath/v2 v2.0.0 h1:iAS9GZahFhyWEH0KLhFEJR+txx1ZhMXxYzu2q5Qo9c0= codeberg.org/gruf/go-fastpath/v2 v2.0.0/go.mod h1:3pPqu5nZjpbRrOqvLyAK7puS1OfEtQvjd6342Cwz56Q= -codeberg.org/gruf/go-ffmpreg v0.2.6 h1:OHlTOF+62/b+VeM3Svg7praweU/NECRIsuhilZLFaO4= -codeberg.org/gruf/go-ffmpreg v0.2.6/go.mod h1:sViRI0BYK2B8PJw4BrOg7DquPD71mZjDfffRAFcDtvk= +codeberg.org/gruf/go-ffmpreg v0.3.1 h1:5qE6sHQbLCbQ4RO7ZL4OKZBN4ViAYfDm9ExT8N0ZE7s= +codeberg.org/gruf/go-ffmpreg v0.3.1/go.mod h1:Ar5nbt3tB2Wr0uoaqV3wDBNwAx+H+AB/mV7Kw7NlZTI= codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf h1:84s/ii8N6lYlskZjHH+DG6jyia8w2mXMZlRwFn8Gs3A= codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf/go.mod h1:zZAICsp5rY7+hxnws2V0ePrWxE0Z2Z/KXcN3p/RQCfk= codeberg.org/gruf/go-kv v1.6.5 h1:ttPf0NA8F79pDqBttSudPTVCZmGncumeNIxmeM9ztz0= @@ -548,8 +548,8 @@ github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03 github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/technologize/otel-go-contrib v1.1.1 h1:wZH9aSPNWZWIkEh3vfaKfMb15AJ80jJ1aVj/4GZdqIw= github.com/technologize/otel-go-contrib v1.1.1/go.mod h1:dCN/wj2WyUO8aFZFdIN+6tfJHImjTML/8r2YVYAy3So= -github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g= -github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= +github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550= +github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E= github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8= github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo= diff --git a/internal/media/ffmpeg/runner.go b/internal/media/ffmpeg/runner.go index 403131ff7..8c59ac752 100644 --- a/internal/media/ffmpeg/runner.go +++ b/internal/media/ffmpeg/runner.go @@ -20,6 +20,7 @@ package ffmpeg import ( "context" + "codeberg.org/gruf/go-ffmpreg/wasm" "github.com/tetratelabs/wazero" ) @@ -65,6 +66,6 @@ func (r *runner) Run(ctx context.Context, cmod wazero.CompiledModule, args Args) // Release slot back to pool on end. defer func() { r.pool <- struct{}{} }() - // Pass to main module runner. - return run(ctx, cmod, args) + // Pass to main module runner function. + return wasm.Run(ctx, runtime, cmod, args) } diff --git a/internal/media/ffmpeg/wasm.go b/internal/media/ffmpeg/wasm.go index 705b16fc3..d76e9017b 100644 --- a/internal/media/ffmpeg/wasm.go +++ b/internal/media/ffmpeg/wasm.go @@ -19,20 +19,18 @@ package ffmpeg import ( "context" - "io" "os" ffmpeglib "codeberg.org/gruf/go-ffmpreg/embed/ffmpeg" ffprobelib "codeberg.org/gruf/go-ffmpreg/embed/ffprobe" + "codeberg.org/gruf/go-ffmpreg/wasm" "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" - "github.com/tetratelabs/wazero/sys" ) // Use all core features required by ffmpeg / ffprobe // (these should be the same but we OR just in case). -const corefeatures = ffprobelib.CoreFeatures | - ffmpeglib.CoreFeatures +const corefeatures = wasm.CoreFeatures var ( // shared WASM runtime instance. @@ -47,65 +45,7 @@ var ( // configuration options to run an instance // of a compiled WebAssembly module that is // run in a typical CLI manner. -type Args struct { - - // Optional further module configuration function. - // (e.g. to mount filesystem dir, set env vars, etc). - Config func(wazero.ModuleConfig) wazero.ModuleConfig - - // Standard FDs. - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - - // CLI args. - Args []string -} - -// run will run the given compiled -// WebAssembly module using given args, -// using the global wazero runtime. -func run( - ctx context.Context, - cmod wazero.CompiledModule, - args Args, -) ( - uint32, // exit code - error, -) { - // Prefix module name as argv0 to args. - cargs := make([]string, len(args.Args)+1) - copy(cargs[1:], args.Args) - cargs[0] = cmod.Name() - - // Create base module config. - modcfg := wazero.NewModuleConfig() - modcfg = modcfg.WithArgs(cargs...) - modcfg = modcfg.WithStdin(args.Stdin) - modcfg = modcfg.WithStdout(args.Stdout) - modcfg = modcfg.WithStderr(args.Stderr) - - if args.Config != nil { - // Pass through config fn. - modcfg = args.Config(modcfg) - } - - // Instantiate the module from precompiled wasm module data. - mod, err := runtime.InstantiateModule(ctx, cmod, modcfg) - - if mod != nil { - // Ensure closed. - _ = mod.Close(ctx) - } - - // Try extract exit code. - switch err := err.(type) { - case *sys.ExitError: - return err.ExitCode(), nil - default: - return 0, err - } -} +type Args = wasm.Args // compileFfmpeg ensures the ffmpeg WebAssembly has been // pre-compiled into memory. If already compiled is a no-op. diff --git a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm index d2b677244..e2083fffd 100644 Binary files a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm and b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm differ diff --git a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/lib.go b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/lib.go index 127d11fde..abe32d7c1 100644 --- a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/lib.go +++ b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/lib.go @@ -3,8 +3,6 @@ package ffmpeg import ( _ "embed" "os" - - "github.com/tetratelabs/wazero/api" ) func init() { @@ -23,14 +21,5 @@ func init() { } } -// CoreFeatures is the WebAssembly Core specification -// features this embedded binary was compiled with. -const CoreFeatures = api.CoreFeatureSIMD | - api.CoreFeatureBulkMemoryOperations | - api.CoreFeatureNonTrappingFloatToIntConversion | - api.CoreFeatureMutableGlobal | - api.CoreFeatureReferenceTypes | - api.CoreFeatureSignExtensionOps - //go:embed ffmpeg.wasm var B []byte diff --git a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm index 98233b43c..b460fa0f9 100644 Binary files a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm and b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm differ diff --git a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/lib.go b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/lib.go index d73d9bed5..c3c3a3df1 100644 --- a/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/lib.go +++ b/vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/lib.go @@ -3,8 +3,6 @@ package ffprobe import ( _ "embed" "os" - - "github.com/tetratelabs/wazero/api" ) func init() { @@ -23,14 +21,5 @@ func init() { } } -// CoreFeatures is the WebAssembly Core specification -// features this embedded binary was compiled with. -const CoreFeatures = api.CoreFeatureSIMD | - api.CoreFeatureBulkMemoryOperations | - api.CoreFeatureNonTrappingFloatToIntConversion | - api.CoreFeatureMutableGlobal | - api.CoreFeatureReferenceTypes | - api.CoreFeatureSignExtensionOps - //go:embed ffprobe.wasm var B []byte diff --git a/vendor/codeberg.org/gruf/go-ffmpreg/wasm/instance.go b/vendor/codeberg.org/gruf/go-ffmpreg/wasm/instance.go new file mode 100644 index 000000000..d2eccd9e9 --- /dev/null +++ b/vendor/codeberg.org/gruf/go-ffmpreg/wasm/instance.go @@ -0,0 +1,89 @@ +package wasm + +import ( + "context" + "io" + "unsafe" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/api" + "github.com/tetratelabs/wazero/sys" +) + +// CoreFeatures are the WebAssembly Core specification +// features our embedded binaries are compiled with. +const CoreFeatures = api.CoreFeatureSIMD | + api.CoreFeatureBulkMemoryOperations | + api.CoreFeatureNonTrappingFloatToIntConversion | + api.CoreFeatureMutableGlobal | + api.CoreFeatureReferenceTypes | + api.CoreFeatureSignExtensionOps + +// Args encompasses a common set of +// configuration options often passed to +// wazero.Runtime on module instantiation. +type Args struct { + + // Optional further module configuration function. + // (e.g. to mount filesystem dir, set env vars, etc). + Config func(wazero.ModuleConfig) wazero.ModuleConfig + + // Standard FDs. + Stdin io.Reader + Stdout io.Writer + Stderr io.Writer + + // CLI args. + Args []string +} + +// Run will run given compiled WebAssembly module +// within the given runtime, with given arguments. +// Returns the exit code, or error. +func Run( + ctx context.Context, + runtime wazero.Runtime, + module wazero.CompiledModule, + args Args, +) (rc uint32, err error) { + + // Prefix arguments with module name. + cargs := make([]string, len(args.Args)+1) + cargs[0] = module.Name() + copy(cargs[1:], args.Args) + + // Prepare new module configuration. + modcfg := wazero.NewModuleConfig() + modcfg = modcfg.WithArgs(cargs...) + modcfg = modcfg.WithStdin(args.Stdin) + modcfg = modcfg.WithStdout(args.Stdout) + modcfg = modcfg.WithStderr(args.Stderr) + + if args.Config != nil { + // Pass through config fn. + modcfg = args.Config(modcfg) + } + + // Instantiate the module from precompiled wasm module data. + mod, err := runtime.InstantiateModule(ctx, module, modcfg) + + if !isNil(mod) { + // Ensure closed. + _ = mod.Close(ctx) + } + + // Try extract exit code. + switch err := err.(type) { + case *sys.ExitError: + return err.ExitCode(), nil + default: + return 0, err + } +} + +// isNil will safely check if 'v' is nil without +// dealing with weird Go interface nil bullshit. +func isNil(i interface{}) bool { + type eface struct{ Type, Data unsafe.Pointer } + return (*(*eface)(unsafe.Pointer(&i))).Data == nil +} diff --git a/vendor/github.com/tetratelabs/wazero/experimental/memory.go b/vendor/github.com/tetratelabs/wazero/experimental/memory.go index e379bf053..26540648b 100644 --- a/vendor/github.com/tetratelabs/wazero/experimental/memory.go +++ b/vendor/github.com/tetratelabs/wazero/experimental/memory.go @@ -35,6 +35,8 @@ type LinearMemory interface { // Notes: // - To back a shared memory, Reallocate can't change the address of the // backing []byte (only its length/capacity may change). + // - Reallocate may return nil if fails to grow the LinearMemory. This + // condition may or may not be handled gracefully by the Wasm module. Reallocate(size uint64) []byte // Free the backing memory buffer. Free() diff --git a/vendor/github.com/tetratelabs/wazero/internal/descriptor/table.go b/vendor/github.com/tetratelabs/wazero/internal/descriptor/table.go index 03761e6ec..a20e19100 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/descriptor/table.go +++ b/vendor/github.com/tetratelabs/wazero/internal/descriptor/table.go @@ -1,6 +1,9 @@ package descriptor -import "math/bits" +import ( + "math/bits" + "slices" +) // Table is a data structure mapping 32 bit descriptor to items. // @@ -37,23 +40,13 @@ func (t *Table[Key, Item]) Len() (n int) { return n } -// grow ensures that t has enough room for n items, potentially reallocating the -// internal buffers if their capacity was too small to hold this many items. +// grow grows the table by n * 64 items. func (t *Table[Key, Item]) grow(n int) { - // Round up to a multiple of 64 since this is the smallest increment due to - // using 64 bits masks. - n = (n*64 + 63) / 64 + total := len(t.masks) + n + t.masks = slices.Grow(t.masks, n)[:total] - if n > len(t.masks) { - masks := make([]uint64, n) - copy(masks, t.masks) - - items := make([]Item, n*64) - copy(items, t.items) - - t.masks = masks - t.items = items - } + total = len(t.items) + n*64 + t.items = slices.Grow(t.items, n*64)[:total] } // Insert inserts the given item to the table, returning the key that it is @@ -78,13 +71,9 @@ insert: } } + // No free slot found, grow the table and retry. offset = len(t.masks) - n := 2 * len(t.masks) - if n == 0 { - n = 1 - } - - t.grow(n) + t.grow(1) goto insert } @@ -109,10 +98,10 @@ func (t *Table[Key, Item]) InsertAt(item Item, key Key) bool { if key < 0 { return false } - if diff := int(key) - t.Len(); diff > 0 { + index := uint(key) / 64 + if diff := int(index) - len(t.masks) + 1; diff > 0 { t.grow(diff) } - index := uint(key) / 64 shift := uint(key) % 64 t.masks[index] |= 1 << shift t.items[key] = item @@ -124,7 +113,8 @@ func (t *Table[Key, Item]) Delete(key Key) { if key < 0 { // invalid key return } - if index, shift := key/64, key%64; int(index) < len(t.masks) { + if index := uint(key) / 64; int(index) < len(t.masks) { + shift := uint(key) % 64 mask := t.masks[index] if (mask & (1 << shift)) != 0 { var zero Item diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go index ee0b453ca..5b5e6e9d0 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go @@ -487,7 +487,7 @@ func (e *engine) setLabelAddress(op *uint64, label label, labelAddressResolution } // ResolveImportedFunction implements wasm.ModuleEngine. -func (e *moduleEngine) ResolveImportedFunction(index, indexInImportedModule wasm.Index, importedModuleEngine wasm.ModuleEngine) { +func (e *moduleEngine) ResolveImportedFunction(index, descFunc, indexInImportedModule wasm.Index, importedModuleEngine wasm.ModuleEngine) { imported := importedModuleEngine.(*moduleEngine) e.functions[index] = imported.functions[indexInImportedModule] } diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go index efa1b9bba..8811feed7 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/module_engine.go @@ -237,7 +237,7 @@ func (m *moduleEngine) putLocalMemory() { } // ResolveImportedFunction implements wasm.ModuleEngine. -func (m *moduleEngine) ResolveImportedFunction(index, indexInImportedModule wasm.Index, importedModuleEngine wasm.ModuleEngine) { +func (m *moduleEngine) ResolveImportedFunction(index, descFunc, indexInImportedModule wasm.Index, importedModuleEngine wasm.ModuleEngine) { executableOffset, moduleCtxOffset, typeIDOffset := m.parent.offsets.ImportedFunctionOffset(index) importedME := importedModuleEngine.(*moduleEngine) @@ -245,12 +245,12 @@ func (m *moduleEngine) ResolveImportedFunction(index, indexInImportedModule wasm indexInImportedModule -= wasm.Index(len(importedME.importedFunctions)) } else { imported := &importedME.importedFunctions[indexInImportedModule] - m.ResolveImportedFunction(index, imported.indexInModule, imported.me) + m.ResolveImportedFunction(index, descFunc, imported.indexInModule, imported.me) return // Recursively resolve the imported function. } offset := importedME.parent.functionOffsets[indexInImportedModule] - typeID := getTypeIDOf(indexInImportedModule, importedME.module) + typeID := m.module.TypeIDs[descFunc] executable := &importedME.parent.executable[offset] // Write functionInstance. binary.LittleEndian.PutUint64(m.opaque[executableOffset:], uint64(uintptr(unsafe.Pointer(executable)))) @@ -261,28 +261,6 @@ func (m *moduleEngine) ResolveImportedFunction(index, indexInImportedModule wasm m.importedFunctions[index] = importedFunction{me: importedME, indexInModule: indexInImportedModule} } -func getTypeIDOf(funcIndex wasm.Index, m *wasm.ModuleInstance) wasm.FunctionTypeID { - source := m.Source - - var typeIndex wasm.Index - if funcIndex >= source.ImportFunctionCount { - funcIndex -= source.ImportFunctionCount - typeIndex = source.FunctionSection[funcIndex] - } else { - var cnt wasm.Index - for i := range source.ImportSection { - if source.ImportSection[i].Type == wasm.ExternTypeFunc { - if cnt == funcIndex { - typeIndex = source.ImportSection[i].DescFunc - break - } - cnt++ - } - } - } - return m.TypeIDs[typeIndex] -} - // ResolveImportedMemory implements wasm.ModuleEngine. func (m *moduleEngine) ResolveImportedMemory(importedModuleEngine wasm.ModuleEngine) { importedME := importedModuleEngine.(*moduleEngine) diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go index ff93415b9..a949bd54d 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/dirfs_supported.go @@ -5,6 +5,7 @@ package sysfs import ( "io/fs" "os" + "path" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" ) @@ -34,6 +35,11 @@ func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno { // Symlink implements the same method as documented on sys.FS func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno { + // Creating a symlink with an absolute path string fails with a "not permitted" error. + // https://github.com/WebAssembly/wasi-filesystem/blob/v0.2.0/path-resolution.md#symlinks + if path.IsAbs(oldName) { + return experimentalsys.EPERM + } // Note: do not resolve `oldName` relative to this dirFS. The link result is always resolved // when dereference the `link` on its usage (e.g. readlink, read, etc). // https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409 diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go index fdbf1fde0..1b6d5f3de 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/file.go @@ -269,7 +269,7 @@ func (f *fsFile) Readdir(n int) (dirents []experimentalsys.Dirent, errno experim if f.reopenDir { // re-open the directory if needed. f.reopenDir = false - if errno = adjustReaddirErr(f, f.closed, f.reopen()); errno != 0 { + if errno = adjustReaddirErr(f, f.closed, f.rewindDir()); errno != 0 { return } } @@ -418,19 +418,25 @@ func seek(s io.Seeker, offset int64, whence int) (int64, experimentalsys.Errno) return newOffset, experimentalsys.UnwrapOSError(err) } -// reopenFile allows re-opening a file for reasons such as applying flags or -// directory iteration. -type reopenFile func() experimentalsys.Errno - -// compile-time check to ensure fsFile.reopen implements reopenFile. -var _ reopenFile = (*fsFile)(nil).reopen - -// reopen implements the same method as documented on reopenFile. -func (f *fsFile) reopen() experimentalsys.Errno { - _ = f.close() - var err error - f.file, err = f.fs.Open(f.name) - return experimentalsys.UnwrapOSError(err) +func (f *fsFile) rewindDir() experimentalsys.Errno { + // Reopen the directory to rewind it. + file, err := f.fs.Open(f.name) + if err != nil { + return experimentalsys.UnwrapOSError(err) + } + fi, err := file.Stat() + if err != nil { + return experimentalsys.UnwrapOSError(err) + } + // Can't check if it's still the same file, + // but is it still a directory, at least? + if !fi.IsDir() { + return experimentalsys.ENOTDIR + } + // Only update f on success. + _ = f.file.Close() + f.file = file + return 0 } // readdirFile allows masking the `Readdir` function on os.File. diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go index 490f0fa68..a9b01eb6a 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go +++ b/vendor/github.com/tetratelabs/wazero/internal/sysfs/osfile.go @@ -83,21 +83,12 @@ func (f *osFile) SetAppend(enable bool) (errno experimentalsys.Errno) { f.flag &= ^experimentalsys.O_APPEND } - // Clear any create or trunc flag, as we are re-opening, not re-creating. - f.flag &= ^(experimentalsys.O_CREAT | experimentalsys.O_TRUNC) - - // appendMode (bool) cannot be changed later, so we have to re-open the - // file. https://github.com/golang/go/blob/go1.20/src/os/file_unix.go#L60 + // appendMode cannot be changed later, so we have to re-open the file + // https://github.com/golang/go/blob/go1.23/src/os/file_unix.go#L60 return fileError(f, f.closed, f.reopen()) } -// compile-time check to ensure osFile.reopen implements reopenFile. -var _ reopenFile = (*osFile)(nil).reopen - func (f *osFile) reopen() (errno experimentalsys.Errno) { - // Clear any create flag, as we are re-opening, not re-creating. - f.flag &= ^experimentalsys.O_CREAT - var ( isDir bool offset int64 @@ -116,22 +107,47 @@ func (f *osFile) reopen() (errno experimentalsys.Errno) { } } - _ = f.close() - f.file, errno = OpenFile(f.path, f.flag, f.perm) + // Clear any create or trunc flag, as we are re-opening, not re-creating. + flag := f.flag &^ (experimentalsys.O_CREAT | experimentalsys.O_TRUNC) + file, errno := OpenFile(f.path, flag, f.perm) + if errno != 0 { + return errno + } + errno = f.checkSameFile(file) if errno != 0 { return errno } if !isDir { - _, err = f.file.Seek(offset, io.SeekStart) + _, err = file.Seek(offset, io.SeekStart) if err != nil { + _ = file.Close() return experimentalsys.UnwrapOSError(err) } } + // Only update f on success. + _ = f.file.Close() + f.file = file + f.fd = file.Fd() return 0 } +func (f *osFile) checkSameFile(osf *os.File) experimentalsys.Errno { + fi1, err := f.file.Stat() + if err != nil { + return experimentalsys.UnwrapOSError(err) + } + fi2, err := osf.Stat() + if err != nil { + return experimentalsys.UnwrapOSError(err) + } + if os.SameFile(fi1, fi2) { + return 0 + } + return experimentalsys.ENOENT +} + // IsNonblock implements the same method as documented on fsapi.File func (f *osFile) IsNonblock() bool { return isNonblock(f) diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/engine.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/engine.go index 61a342ef2..8c387e9e1 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/engine.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/engine.go @@ -44,9 +44,10 @@ type ModuleEngine interface { // ResolveImportedFunction is used to add imported functions needed to make this ModuleEngine fully functional. // - `index` is the function Index of this imported function. + // - `descFunc` is the type Index in Module.TypeSection of this imported function. It corresponds to Import.DescFunc. // - `indexInImportedModule` is the function Index of the imported function in the imported module. // - `importedModuleEngine` is the ModuleEngine for the imported ModuleInstance. - ResolveImportedFunction(index, indexInImportedModule Index, importedModuleEngine ModuleEngine) + ResolveImportedFunction(index, descFunc, indexInImportedModule Index, importedModuleEngine ModuleEngine) // ResolveImportedMemory is called when this module imports a memory from another module. ResolveImportedMemory(importedModuleEngine ModuleEngine) diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go index 8e072fd12..9a1f0c6d1 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/memory.go @@ -77,6 +77,7 @@ func NewMemoryInstance(memSec *Memory, allocator experimental.MemoryAllocator, m if allocator != nil { expBuffer = allocator.Allocate(capBytes, maxBytes) buffer = expBuffer.Reallocate(minBytes) + _ = buffer[:minBytes] // Bounds check that the minimum was allocated. } else if memSec.IsShared { // Shared memory needs a fixed buffer, so allocate with the maximum size. // @@ -238,12 +239,15 @@ func (m *MemoryInstance) Grow(delta uint32) (result uint32, ok bool) { return currentPages, true } - // If exceeds the max of memory size, we push -1 according to the spec. newPages := currentPages + delta if newPages > m.Max || int32(delta) < 0 { return 0, false } else if m.expBuffer != nil { buffer := m.expBuffer.Reallocate(MemoryPagesToBytesNum(newPages)) + if buffer == nil { + // Allocator failed to grow. + return 0, false + } if m.Shared { if unsafe.SliceData(buffer) != unsafe.SliceData(m.Buffer) { panic("shared memory cannot move, this is a bug in the memory allocator") diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go index dda6e5b63..c7909c67c 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/store.go @@ -446,7 +446,7 @@ func (m *ModuleInstance) resolveImports(ctx context.Context, module *Module) (er return } - m.Engine.ResolveImportedFunction(i.IndexPerType, imported.Index, importedModule.Engine) + m.Engine.ResolveImportedFunction(i.IndexPerType, i.DescFunc, imported.Index, importedModule.Engine) case ExternTypeTable: expected := i.DescTable importedTable := importedModule.Tables[imported.Index] diff --git a/vendor/github.com/tetratelabs/wazero/sys/stat.go b/vendor/github.com/tetratelabs/wazero/sys/stat.go index bb7b9e5d3..328885545 100644 --- a/vendor/github.com/tetratelabs/wazero/sys/stat.go +++ b/vendor/github.com/tetratelabs/wazero/sys/stat.go @@ -29,9 +29,7 @@ type EpochNanos = int64 // # Notes // // - This is used for WebAssembly ABI emulating the POSIX `stat` system call. -// Fields included are required for WebAssembly ABI including wasip1 -// (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2). See -// https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html +// See https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html // - Fields here are required for WebAssembly ABI including wasip1 // (a.k.a. wasix) and wasi-filesystem (a.k.a. wasip2). // - This isn't the same as syscall.Stat_t because wazero supports Windows, diff --git a/vendor/modules.txt b/vendor/modules.txt index ea6f6b10a..cf4fa2d5d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -24,10 +24,11 @@ codeberg.org/gruf/go-fastcopy # codeberg.org/gruf/go-fastpath/v2 v2.0.0 ## explicit; go 1.14 codeberg.org/gruf/go-fastpath/v2 -# codeberg.org/gruf/go-ffmpreg v0.2.6 +# codeberg.org/gruf/go-ffmpreg v0.3.1 ## explicit; go 1.22.0 codeberg.org/gruf/go-ffmpreg/embed/ffmpeg codeberg.org/gruf/go-ffmpreg/embed/ffprobe +codeberg.org/gruf/go-ffmpreg/wasm # codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf ## explicit; go 1.21 codeberg.org/gruf/go-iotools @@ -844,7 +845,7 @@ github.com/tdewolff/parse/v2/strconv # github.com/technologize/otel-go-contrib v1.1.1 ## explicit; go 1.17 github.com/technologize/otel-go-contrib/otelginmetrics -# github.com/tetratelabs/wazero v1.8.0 +# github.com/tetratelabs/wazero v1.8.1 ## explicit; go 1.21 github.com/tetratelabs/wazero github.com/tetratelabs/wazero/api