mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-30 16:42:26 -05:00
[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/).
This commit is contained in:
parent
cce21c11cb
commit
1e7b32490d
398 changed files with 86174 additions and 684 deletions
48
vendor/github.com/tetratelabs/wazero/experimental/checkpoint.go
generated
vendored
Normal file
48
vendor/github.com/tetratelabs/wazero/experimental/checkpoint.go
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package experimental
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/internal/expctxkeys"
|
||||
)
|
||||
|
||||
// Snapshot holds the execution state at the time of a Snapshotter.Snapshot call.
|
||||
type Snapshot interface {
|
||||
// Restore sets the Wasm execution state to the capture. Because a host function
|
||||
// calling this is resetting the pointer to the executation stack, the host function
|
||||
// will not be able to return values in the normal way. ret is a slice of values the
|
||||
// host function intends to return from the restored function.
|
||||
Restore(ret []uint64)
|
||||
}
|
||||
|
||||
// Snapshotter allows host functions to snapshot the WebAssembly execution environment.
|
||||
type Snapshotter interface {
|
||||
// Snapshot captures the current execution state.
|
||||
Snapshot() Snapshot
|
||||
}
|
||||
|
||||
// EnableSnapshotterKey is a context key to indicate that snapshotting should be enabled.
|
||||
// The context.Context passed to a exported function invocation should have this key set
|
||||
// to a non-nil value, and host functions will be able to retrieve it using SnapshotterKey.
|
||||
//
|
||||
// Deprecated: use WithSnapshotter to enable snapshots.
|
||||
type EnableSnapshotterKey = expctxkeys.EnableSnapshotterKey
|
||||
|
||||
// WithSnapshotter enables snapshots.
|
||||
// Passing the returned context to a exported function invocation enables snapshots,
|
||||
// and allows host functions to retrieve the Snapshotter using GetSnapshotter.
|
||||
func WithSnapshotter(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, expctxkeys.EnableSnapshotterKey{}, struct{}{})
|
||||
}
|
||||
|
||||
// SnapshotterKey is a context key to access a Snapshotter from a host function.
|
||||
// It is only present if EnableSnapshotter was set in the function invocation context.
|
||||
//
|
||||
// Deprecated: use GetSnapshotter to get the snapshotter.
|
||||
type SnapshotterKey = expctxkeys.SnapshotterKey
|
||||
|
||||
// GetSnapshotter gets the Snapshotter from a host function.
|
||||
// It is only present if WithSnapshotter was called with the function invocation context.
|
||||
func GetSnapshotter(ctx context.Context) Snapshotter {
|
||||
return ctx.Value(expctxkeys.SnapshotterKey{}).(Snapshotter)
|
||||
}
|
||||
63
vendor/github.com/tetratelabs/wazero/experimental/close.go
generated
vendored
Normal file
63
vendor/github.com/tetratelabs/wazero/experimental/close.go
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
package experimental
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/internal/expctxkeys"
|
||||
)
|
||||
|
||||
// CloseNotifier is a notification hook, invoked when a module is closed.
|
||||
//
|
||||
// Note: This is experimental progress towards #1197, and likely to change. Do
|
||||
// not expose this in shared libraries as it can cause version locks.
|
||||
type CloseNotifier interface {
|
||||
// CloseNotify is a notification that occurs *before* an api.Module is
|
||||
// closed. `exitCode` is zero on success or in the case there was no exit
|
||||
// code.
|
||||
//
|
||||
// Notes:
|
||||
// - This does not return an error because the module will be closed
|
||||
// unconditionally.
|
||||
// - Do not panic from this function as it doing so could cause resource
|
||||
// leaks.
|
||||
// - While this is only called once per module, if configured for
|
||||
// multiple modules, it will be called for each, e.g. on runtime close.
|
||||
CloseNotify(ctx context.Context, exitCode uint32)
|
||||
}
|
||||
|
||||
// ^-- Note: This might need to be a part of the listener or become a part of
|
||||
// host state implementation. For example, if this is used to implement state
|
||||
// cleanup for host modules, possibly something like below would be better, as
|
||||
// it could be implemented in a way that allows concurrent module use.
|
||||
//
|
||||
// // key is like a context key, stateFactory is invoked per instantiate and
|
||||
// // is associated with the key (exposed as `Module.State` similar to go
|
||||
// // context). Using a key is better than the module name because we can
|
||||
// // de-dupe it for host modules that can be instantiated into different
|
||||
// // names. Also, you can make the key package private.
|
||||
// HostModuleBuilder.WithState(key any, stateFactory func() Cleanup)`
|
||||
//
|
||||
// Such a design could work to isolate state only needed for wasip1, for
|
||||
// example the dirent cache. However, if end users use this for different
|
||||
// things, we may need separate designs.
|
||||
//
|
||||
// In summary, the purpose of this iteration is to identify projects that
|
||||
// would use something like this, and then we can figure out which way it
|
||||
// should go.
|
||||
|
||||
// CloseNotifyFunc is a convenience for defining inlining a CloseNotifier.
|
||||
type CloseNotifyFunc func(ctx context.Context, exitCode uint32)
|
||||
|
||||
// CloseNotify implements CloseNotifier.CloseNotify.
|
||||
func (f CloseNotifyFunc) CloseNotify(ctx context.Context, exitCode uint32) {
|
||||
f(ctx, exitCode)
|
||||
}
|
||||
|
||||
// WithCloseNotifier registers the given CloseNotifier into the given
|
||||
// context.Context.
|
||||
func WithCloseNotifier(ctx context.Context, notifier CloseNotifier) context.Context {
|
||||
if notifier != nil {
|
||||
return context.WithValue(ctx, expctxkeys.CloseNotifierKey{}, notifier)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
41
vendor/github.com/tetratelabs/wazero/experimental/experimental.go
generated
vendored
Normal file
41
vendor/github.com/tetratelabs/wazero/experimental/experimental.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Package experimental includes features we aren't yet sure about. These are enabled with context.Context keys.
|
||||
//
|
||||
// Note: All features here may be changed or deleted at any time, so use with caution!
|
||||
package experimental
|
||||
|
||||
import (
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
)
|
||||
|
||||
// InternalModule is an api.Module that exposes additional
|
||||
// information.
|
||||
type InternalModule interface {
|
||||
api.Module
|
||||
|
||||
// NumGlobal returns the count of all globals in the module.
|
||||
NumGlobal() int
|
||||
|
||||
// Global provides a read-only view for a given global index.
|
||||
//
|
||||
// The methods panics if i is out of bounds.
|
||||
Global(i int) api.Global
|
||||
}
|
||||
|
||||
// ProgramCounter is an opaque value representing a specific execution point in
|
||||
// a module. It is meant to be used with Function.SourceOffsetForPC and
|
||||
// StackIterator.
|
||||
type ProgramCounter uint64
|
||||
|
||||
// InternalFunction exposes some information about a function instance.
|
||||
type InternalFunction interface {
|
||||
// Definition provides introspection into the function's names and
|
||||
// signature.
|
||||
Definition() api.FunctionDefinition
|
||||
|
||||
// SourceOffsetForPC resolves a program counter into its corresponding
|
||||
// offset in the Code section of the module this function belongs to.
|
||||
// The source offset is meant to help map the function calls to their
|
||||
// location in the original source files. Returns 0 if the offset cannot
|
||||
// be calculated.
|
||||
SourceOffsetForPC(pc ProgramCounter) uint64
|
||||
}
|
||||
15
vendor/github.com/tetratelabs/wazero/experimental/features.go
generated
vendored
Normal file
15
vendor/github.com/tetratelabs/wazero/experimental/features.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package experimental
|
||||
|
||||
import "github.com/tetratelabs/wazero/api"
|
||||
|
||||
// CoreFeaturesThreads enables threads instructions ("threads").
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - The instruction list is too long to enumerate in godoc.
|
||||
// See https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md
|
||||
// - Atomic operations are guest-only until api.Memory or otherwise expose them to host functions.
|
||||
// - On systems without mmap available, the memory will pre-allocate to the maximum size. Many
|
||||
// binaries will use a theroetical maximum like 4GB, so if using such a binary on a system
|
||||
// without mmap, consider editing the binary to reduce the max size setting of memory.
|
||||
const CoreFeaturesThreads = api.CoreFeatureSIMD << 1
|
||||
330
vendor/github.com/tetratelabs/wazero/experimental/listener.go
generated
vendored
Normal file
330
vendor/github.com/tetratelabs/wazero/experimental/listener.go
generated
vendored
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
package experimental
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/internal/expctxkeys"
|
||||
)
|
||||
|
||||
// StackIterator allows iterating on each function of the call stack, starting
|
||||
// from the top. At least one call to Next() is required to start the iteration.
|
||||
//
|
||||
// Note: The iterator provides a view of the call stack at the time of
|
||||
// iteration. As a result, parameter values may be different than the ones their
|
||||
// function was called with.
|
||||
type StackIterator interface {
|
||||
// Next moves the iterator to the next function in the stack. Returns
|
||||
// false if it reached the bottom of the stack.
|
||||
Next() bool
|
||||
// Function describes the function called by the current frame.
|
||||
Function() InternalFunction
|
||||
// ProgramCounter returns the program counter associated with the
|
||||
// function call.
|
||||
ProgramCounter() ProgramCounter
|
||||
}
|
||||
|
||||
// FunctionListenerFactoryKey is a context.Context Value key.
|
||||
// Its associated value should be a FunctionListenerFactory.
|
||||
//
|
||||
// Deprecated: use WithFunctionListenerFactory to enable snapshots.
|
||||
type FunctionListenerFactoryKey = expctxkeys.FunctionListenerFactoryKey
|
||||
|
||||
// WithFunctionListenerFactory registers a FunctionListenerFactory
|
||||
// with the context.
|
||||
func WithFunctionListenerFactory(ctx context.Context, factory FunctionListenerFactory) context.Context {
|
||||
return context.WithValue(ctx, expctxkeys.FunctionListenerFactoryKey{}, factory)
|
||||
}
|
||||
|
||||
// FunctionListenerFactory returns FunctionListeners to be notified when a
|
||||
// function is called.
|
||||
type FunctionListenerFactory interface {
|
||||
// NewFunctionListener returns a FunctionListener for a defined function.
|
||||
// If nil is returned, no listener will be notified.
|
||||
NewFunctionListener(api.FunctionDefinition) FunctionListener
|
||||
// ^^ A single instance can be returned to avoid instantiating a listener
|
||||
// per function, especially as they may be thousands of functions. Shared
|
||||
// listeners use their FunctionDefinition parameter to clarify.
|
||||
}
|
||||
|
||||
// FunctionListener can be registered for any function via
|
||||
// FunctionListenerFactory to be notified when the function is called.
|
||||
type FunctionListener interface {
|
||||
// Before is invoked before a function is called.
|
||||
//
|
||||
// There is always one corresponding call to After or Abort for each call to
|
||||
// Before. This guarantee allows the listener to maintain an internal stack
|
||||
// to perform correlations between the entry and exit of functions.
|
||||
//
|
||||
// # Params
|
||||
//
|
||||
// - ctx: the context of the caller function which must be the same
|
||||
// instance or parent of the result.
|
||||
// - mod: the calling module.
|
||||
// - def: the function definition.
|
||||
// - params: api.ValueType encoded parameters.
|
||||
// - stackIterator: iterator on the call stack. At least one entry is
|
||||
// guaranteed (the called function), whose Args() will be equal to
|
||||
// params. The iterator will be reused between calls to Before.
|
||||
//
|
||||
// Note: api.Memory is meant for inspection, not modification.
|
||||
// mod can be cast to InternalModule to read non-exported globals.
|
||||
Before(ctx context.Context, mod api.Module, def api.FunctionDefinition, params []uint64, stackIterator StackIterator)
|
||||
|
||||
// After is invoked after a function is called.
|
||||
//
|
||||
// # Params
|
||||
//
|
||||
// - ctx: the context of the caller function.
|
||||
// - mod: the calling module.
|
||||
// - def: the function definition.
|
||||
// - results: api.ValueType encoded results.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - api.Memory is meant for inspection, not modification.
|
||||
// - This is not called when a host function panics, or a guest function traps.
|
||||
// See Abort for more details.
|
||||
After(ctx context.Context, mod api.Module, def api.FunctionDefinition, results []uint64)
|
||||
|
||||
// Abort is invoked when a function does not return due to a trap or panic.
|
||||
//
|
||||
// # Params
|
||||
//
|
||||
// - ctx: the context of the caller function.
|
||||
// - mod: the calling module.
|
||||
// - def: the function definition.
|
||||
// - err: the error value representing the reason why the function aborted.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - api.Memory is meant for inspection, not modification.
|
||||
Abort(ctx context.Context, mod api.Module, def api.FunctionDefinition, err error)
|
||||
}
|
||||
|
||||
// FunctionListenerFunc is a function type implementing the FunctionListener
|
||||
// interface, making it possible to use regular functions and methods as
|
||||
// listeners of function invocation.
|
||||
//
|
||||
// The FunctionListener interface declares two methods (Before and After),
|
||||
// but this type invokes its value only when Before is called. It is best
|
||||
// suites for cases where the host does not need to perform correlation
|
||||
// between the start and end of the function call.
|
||||
type FunctionListenerFunc func(context.Context, api.Module, api.FunctionDefinition, []uint64, StackIterator)
|
||||
|
||||
// Before satisfies the FunctionListener interface, calls f.
|
||||
func (f FunctionListenerFunc) Before(ctx context.Context, mod api.Module, def api.FunctionDefinition, params []uint64, stackIterator StackIterator) {
|
||||
f(ctx, mod, def, params, stackIterator)
|
||||
}
|
||||
|
||||
// After is declared to satisfy the FunctionListener interface, but it does
|
||||
// nothing.
|
||||
func (f FunctionListenerFunc) After(context.Context, api.Module, api.FunctionDefinition, []uint64) {
|
||||
}
|
||||
|
||||
// Abort is declared to satisfy the FunctionListener interface, but it does
|
||||
// nothing.
|
||||
func (f FunctionListenerFunc) Abort(context.Context, api.Module, api.FunctionDefinition, error) {
|
||||
}
|
||||
|
||||
// FunctionListenerFactoryFunc is a function type implementing the
|
||||
// FunctionListenerFactory interface, making it possible to use regular
|
||||
// functions and methods as factory of function listeners.
|
||||
type FunctionListenerFactoryFunc func(api.FunctionDefinition) FunctionListener
|
||||
|
||||
// NewFunctionListener satisfies the FunctionListenerFactory interface, calls f.
|
||||
func (f FunctionListenerFactoryFunc) NewFunctionListener(def api.FunctionDefinition) FunctionListener {
|
||||
return f(def)
|
||||
}
|
||||
|
||||
// MultiFunctionListenerFactory constructs a FunctionListenerFactory which
|
||||
// combines the listeners created by each of the factories passed as arguments.
|
||||
//
|
||||
// This function is useful when multiple listeners need to be hooked to a module
|
||||
// because the propagation mechanism based on installing a listener factory in
|
||||
// the context.Context used when instantiating modules allows for a single
|
||||
// listener to be installed.
|
||||
//
|
||||
// The stack iterator passed to the Before method is reset so that each listener
|
||||
// can iterate the call stack independently without impacting the ability of
|
||||
// other listeners to do so.
|
||||
func MultiFunctionListenerFactory(factories ...FunctionListenerFactory) FunctionListenerFactory {
|
||||
multi := make(multiFunctionListenerFactory, len(factories))
|
||||
copy(multi, factories)
|
||||
return multi
|
||||
}
|
||||
|
||||
type multiFunctionListenerFactory []FunctionListenerFactory
|
||||
|
||||
func (multi multiFunctionListenerFactory) NewFunctionListener(def api.FunctionDefinition) FunctionListener {
|
||||
var lstns []FunctionListener
|
||||
for _, factory := range multi {
|
||||
if lstn := factory.NewFunctionListener(def); lstn != nil {
|
||||
lstns = append(lstns, lstn)
|
||||
}
|
||||
}
|
||||
switch len(lstns) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return lstns[0]
|
||||
default:
|
||||
return &multiFunctionListener{lstns: lstns}
|
||||
}
|
||||
}
|
||||
|
||||
type multiFunctionListener struct {
|
||||
lstns []FunctionListener
|
||||
stack stackIterator
|
||||
}
|
||||
|
||||
func (multi *multiFunctionListener) Before(ctx context.Context, mod api.Module, def api.FunctionDefinition, params []uint64, si StackIterator) {
|
||||
multi.stack.base = si
|
||||
for _, lstn := range multi.lstns {
|
||||
multi.stack.index = -1
|
||||
lstn.Before(ctx, mod, def, params, &multi.stack)
|
||||
}
|
||||
}
|
||||
|
||||
func (multi *multiFunctionListener) After(ctx context.Context, mod api.Module, def api.FunctionDefinition, results []uint64) {
|
||||
for _, lstn := range multi.lstns {
|
||||
lstn.After(ctx, mod, def, results)
|
||||
}
|
||||
}
|
||||
|
||||
func (multi *multiFunctionListener) Abort(ctx context.Context, mod api.Module, def api.FunctionDefinition, err error) {
|
||||
for _, lstn := range multi.lstns {
|
||||
lstn.Abort(ctx, mod, def, err)
|
||||
}
|
||||
}
|
||||
|
||||
type stackIterator struct {
|
||||
base StackIterator
|
||||
index int
|
||||
pcs []uint64
|
||||
fns []InternalFunction
|
||||
}
|
||||
|
||||
func (si *stackIterator) Next() bool {
|
||||
if si.base != nil {
|
||||
si.pcs = si.pcs[:0]
|
||||
si.fns = si.fns[:0]
|
||||
|
||||
for si.base.Next() {
|
||||
si.pcs = append(si.pcs, uint64(si.base.ProgramCounter()))
|
||||
si.fns = append(si.fns, si.base.Function())
|
||||
}
|
||||
|
||||
si.base = nil
|
||||
}
|
||||
si.index++
|
||||
return si.index < len(si.pcs)
|
||||
}
|
||||
|
||||
func (si *stackIterator) ProgramCounter() ProgramCounter {
|
||||
return ProgramCounter(si.pcs[si.index])
|
||||
}
|
||||
|
||||
func (si *stackIterator) Function() InternalFunction {
|
||||
return si.fns[si.index]
|
||||
}
|
||||
|
||||
// StackFrame represents a frame on the call stack.
|
||||
type StackFrame struct {
|
||||
Function api.Function
|
||||
Params []uint64
|
||||
Results []uint64
|
||||
PC uint64
|
||||
SourceOffset uint64
|
||||
}
|
||||
|
||||
type internalFunction struct {
|
||||
definition api.FunctionDefinition
|
||||
sourceOffset uint64
|
||||
}
|
||||
|
||||
func (f internalFunction) Definition() api.FunctionDefinition {
|
||||
return f.definition
|
||||
}
|
||||
|
||||
func (f internalFunction) SourceOffsetForPC(pc ProgramCounter) uint64 {
|
||||
return f.sourceOffset
|
||||
}
|
||||
|
||||
// stackFrameIterator is an implementation of the experimental.stackFrameIterator
|
||||
// interface.
|
||||
type stackFrameIterator struct {
|
||||
index int
|
||||
stack []StackFrame
|
||||
fndef []api.FunctionDefinition
|
||||
}
|
||||
|
||||
func (si *stackFrameIterator) Next() bool {
|
||||
si.index++
|
||||
return si.index < len(si.stack)
|
||||
}
|
||||
|
||||
func (si *stackFrameIterator) Function() InternalFunction {
|
||||
return internalFunction{
|
||||
definition: si.fndef[si.index],
|
||||
sourceOffset: si.stack[si.index].SourceOffset,
|
||||
}
|
||||
}
|
||||
|
||||
func (si *stackFrameIterator) ProgramCounter() ProgramCounter {
|
||||
return ProgramCounter(si.stack[si.index].PC)
|
||||
}
|
||||
|
||||
// NewStackIterator constructs a stack iterator from a list of stack frames.
|
||||
// The top most frame is the last one.
|
||||
func NewStackIterator(stack ...StackFrame) StackIterator {
|
||||
si := &stackFrameIterator{
|
||||
index: -1,
|
||||
stack: make([]StackFrame, len(stack)),
|
||||
fndef: make([]api.FunctionDefinition, len(stack)),
|
||||
}
|
||||
for i := range stack {
|
||||
si.stack[i] = stack[len(stack)-(i+1)]
|
||||
}
|
||||
// The size of function definition is only one pointer which should allow
|
||||
// the compiler to optimize the conversion to api.FunctionDefinition; but
|
||||
// the presence of internal.WazeroOnlyType, despite being defined as an
|
||||
// empty struct, forces a heap allocation that we amortize by caching the
|
||||
// result.
|
||||
for i, frame := range stack {
|
||||
si.fndef[i] = frame.Function.Definition()
|
||||
}
|
||||
return si
|
||||
}
|
||||
|
||||
// BenchmarkFunctionListener implements a benchmark for function listeners.
|
||||
//
|
||||
// The benchmark calls Before and After methods repeatedly using the provided
|
||||
// module an stack frames to invoke the methods.
|
||||
//
|
||||
// The stack frame is a representation of the call stack that the Before method
|
||||
// will be invoked with. The top of the stack is stored at index zero. The stack
|
||||
// must contain at least one frame or the benchmark will fail.
|
||||
func BenchmarkFunctionListener(n int, module api.Module, stack []StackFrame, listener FunctionListener) {
|
||||
if len(stack) == 0 {
|
||||
panic("cannot benchmark function listener with an empty stack")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
def := stack[0].Function.Definition()
|
||||
params := stack[0].Params
|
||||
results := stack[0].Results
|
||||
stackIterator := &stackIterator{base: NewStackIterator(stack...)}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
stackIterator.index = -1
|
||||
listener.Before(ctx, module, def, params, stackIterator)
|
||||
listener.After(ctx, module, def, results)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: the calls to Abort are not yet tested in internal/testing/enginetest,
|
||||
// but they are validated indirectly in tests which exercise host logging,
|
||||
// like Test_procExit in imports/wasi_snapshot_preview1. Eventually we should
|
||||
// add dedicated tests to validate the behavior of the interpreter and compiler
|
||||
// engines independently.
|
||||
50
vendor/github.com/tetratelabs/wazero/experimental/memory.go
generated
vendored
Normal file
50
vendor/github.com/tetratelabs/wazero/experimental/memory.go
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package experimental
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/internal/expctxkeys"
|
||||
)
|
||||
|
||||
// MemoryAllocator is a memory allocation hook,
|
||||
// invoked to create a LinearMemory.
|
||||
type MemoryAllocator interface {
|
||||
// Allocate should create a new LinearMemory with the given specification:
|
||||
// cap is the suggested initial capacity for the backing []byte,
|
||||
// and max the maximum length that will ever be requested.
|
||||
//
|
||||
// Notes:
|
||||
// - To back a shared memory, the address of the backing []byte cannot
|
||||
// change. This is checked at runtime. Implementations should document
|
||||
// if the returned LinearMemory meets this requirement.
|
||||
Allocate(cap, max uint64) LinearMemory
|
||||
}
|
||||
|
||||
// MemoryAllocatorFunc is a convenience for defining inlining a MemoryAllocator.
|
||||
type MemoryAllocatorFunc func(cap, max uint64) LinearMemory
|
||||
|
||||
// Allocate implements MemoryAllocator.Allocate.
|
||||
func (f MemoryAllocatorFunc) Allocate(cap, max uint64) LinearMemory {
|
||||
return f(cap, max)
|
||||
}
|
||||
|
||||
// LinearMemory is an expandable []byte that backs a Wasm linear memory.
|
||||
type LinearMemory interface {
|
||||
// Reallocates the linear memory to size bytes in length.
|
||||
//
|
||||
// Notes:
|
||||
// - To back a shared memory, Reallocate can't change the address of the
|
||||
// backing []byte (only its length/capacity may change).
|
||||
Reallocate(size uint64) []byte
|
||||
// Free the backing memory buffer.
|
||||
Free()
|
||||
}
|
||||
|
||||
// WithMemoryAllocator registers the given MemoryAllocator into the given
|
||||
// context.Context.
|
||||
func WithMemoryAllocator(ctx context.Context, allocator MemoryAllocator) context.Context {
|
||||
if allocator != nil {
|
||||
return context.WithValue(ctx, expctxkeys.MemoryAllocatorKey{}, allocator)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
92
vendor/github.com/tetratelabs/wazero/experimental/sys/dir.go
generated
vendored
Normal file
92
vendor/github.com/tetratelabs/wazero/experimental/sys/dir.go
generated
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
package sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
|
||||
"github.com/tetratelabs/wazero/sys"
|
||||
)
|
||||
|
||||
// FileType is fs.FileMode masked on fs.ModeType. For example, zero is a
|
||||
// regular file, fs.ModeDir is a directory and fs.ModeIrregular is unknown.
|
||||
//
|
||||
// Note: This is defined by Linux, not POSIX.
|
||||
type FileType = fs.FileMode
|
||||
|
||||
// Dirent is an entry read from a directory via File.Readdir.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This extends `dirent` defined in POSIX with some fields defined by
|
||||
// Linux. See https://man7.org/linux/man-pages/man3/readdir.3.html and
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/dirent.h.html
|
||||
// - This has a subset of fields defined in sys.Stat_t. Notably, there is no
|
||||
// field corresponding to Stat_t.Dev because that value will be constant
|
||||
// for all files in a directory. To get the Dev value, call File.Stat on
|
||||
// the directory File.Readdir was called on.
|
||||
type Dirent struct {
|
||||
// Ino is the file serial number, or zero if not available. See Ino for
|
||||
// more details including impact returning a zero value.
|
||||
Ino sys.Inode
|
||||
|
||||
// Name is the base name of the directory entry. Empty is invalid.
|
||||
Name string
|
||||
|
||||
// Type is fs.FileMode masked on fs.ModeType. For example, zero is a
|
||||
// regular file, fs.ModeDir is a directory and fs.ModeIrregular is unknown.
|
||||
//
|
||||
// Note: This is defined by Linux, not POSIX.
|
||||
Type fs.FileMode
|
||||
}
|
||||
|
||||
func (d *Dirent) String() string {
|
||||
return fmt.Sprintf("name=%s, type=%v, ino=%d", d.Name, d.Type, d.Ino)
|
||||
}
|
||||
|
||||
// IsDir returns true if the Type is fs.ModeDir.
|
||||
func (d *Dirent) IsDir() bool {
|
||||
return d.Type == fs.ModeDir
|
||||
}
|
||||
|
||||
// DirFile is embeddable to reduce the amount of functions to implement a file.
|
||||
type DirFile struct{}
|
||||
|
||||
// IsAppend implements File.IsAppend
|
||||
func (DirFile) IsAppend() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SetAppend implements File.SetAppend
|
||||
func (DirFile) SetAppend(bool) Errno {
|
||||
return EISDIR
|
||||
}
|
||||
|
||||
// IsDir implements File.IsDir
|
||||
func (DirFile) IsDir() (bool, Errno) {
|
||||
return true, 0
|
||||
}
|
||||
|
||||
// Read implements File.Read
|
||||
func (DirFile) Read([]byte) (int, Errno) {
|
||||
return 0, EISDIR
|
||||
}
|
||||
|
||||
// Pread implements File.Pread
|
||||
func (DirFile) Pread([]byte, int64) (int, Errno) {
|
||||
return 0, EISDIR
|
||||
}
|
||||
|
||||
// Write implements File.Write
|
||||
func (DirFile) Write([]byte) (int, Errno) {
|
||||
return 0, EISDIR
|
||||
}
|
||||
|
||||
// Pwrite implements File.Pwrite
|
||||
func (DirFile) Pwrite([]byte, int64) (int, Errno) {
|
||||
return 0, EISDIR
|
||||
}
|
||||
|
||||
// Truncate implements File.Truncate
|
||||
func (DirFile) Truncate(int64) Errno {
|
||||
return EISDIR
|
||||
}
|
||||
98
vendor/github.com/tetratelabs/wazero/experimental/sys/errno.go
generated
vendored
Normal file
98
vendor/github.com/tetratelabs/wazero/experimental/sys/errno.go
generated
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
package sys
|
||||
|
||||
import "strconv"
|
||||
|
||||
// Errno is a subset of POSIX errno used by wazero interfaces. Zero is not an
|
||||
// error. Other values should not be interpreted numerically, rather by constants
|
||||
// prefixed with 'E'.
|
||||
//
|
||||
// See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
|
||||
type Errno uint16
|
||||
|
||||
// ^-- Note: This will eventually move to the public /sys package. It is
|
||||
// experimental until we audit the socket related APIs to ensure we have all
|
||||
// the Errno it returns, and we export fs.FS. This is not in /internal/sys as
|
||||
// that would introduce a package cycle.
|
||||
|
||||
// This is a subset of errors to reduce implementation burden. `wasip1` defines
|
||||
// almost all POSIX error numbers, but not all are used in practice. wazero
|
||||
// will add ones needed in POSIX order, as needed by functions that explicitly
|
||||
// document returning them.
|
||||
//
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-errno-enumu16
|
||||
const (
|
||||
EACCES Errno = iota + 1
|
||||
EAGAIN
|
||||
EBADF
|
||||
EEXIST
|
||||
EFAULT
|
||||
EINTR
|
||||
EINVAL
|
||||
EIO
|
||||
EISDIR
|
||||
ELOOP
|
||||
ENAMETOOLONG
|
||||
ENOENT
|
||||
ENOSYS
|
||||
ENOTDIR
|
||||
ERANGE
|
||||
ENOTEMPTY
|
||||
ENOTSOCK
|
||||
ENOTSUP
|
||||
EPERM
|
||||
EROFS
|
||||
|
||||
// NOTE ENOTCAPABLE is defined in wasip1, but not in POSIX. wasi-libc
|
||||
// converts it to EBADF, ESPIPE or EINVAL depending on the call site.
|
||||
// It isn't known if compilers who don't use ENOTCAPABLE would crash on it.
|
||||
)
|
||||
|
||||
// Error implements error
|
||||
func (e Errno) Error() string {
|
||||
switch e {
|
||||
case 0: // not an error
|
||||
return "success"
|
||||
case EACCES:
|
||||
return "permission denied"
|
||||
case EAGAIN:
|
||||
return "resource unavailable, try again"
|
||||
case EBADF:
|
||||
return "bad file descriptor"
|
||||
case EEXIST:
|
||||
return "file exists"
|
||||
case EFAULT:
|
||||
return "bad address"
|
||||
case EINTR:
|
||||
return "interrupted function"
|
||||
case EINVAL:
|
||||
return "invalid argument"
|
||||
case EIO:
|
||||
return "input/output error"
|
||||
case EISDIR:
|
||||
return "is a directory"
|
||||
case ELOOP:
|
||||
return "too many levels of symbolic links"
|
||||
case ENAMETOOLONG:
|
||||
return "filename too long"
|
||||
case ENOENT:
|
||||
return "no such file or directory"
|
||||
case ENOSYS:
|
||||
return "functionality not supported"
|
||||
case ENOTDIR:
|
||||
return "not a directory or a symbolic link to a directory"
|
||||
case ERANGE:
|
||||
return "result too large"
|
||||
case ENOTEMPTY:
|
||||
return "directory not empty"
|
||||
case ENOTSOCK:
|
||||
return "not a socket"
|
||||
case ENOTSUP:
|
||||
return "not supported (may be the same value as [EOPNOTSUPP])"
|
||||
case EPERM:
|
||||
return "operation not permitted"
|
||||
case EROFS:
|
||||
return "read-only file system"
|
||||
default:
|
||||
return "Errno(" + strconv.Itoa(int(e)) + ")"
|
||||
}
|
||||
}
|
||||
45
vendor/github.com/tetratelabs/wazero/experimental/sys/error.go
generated
vendored
Normal file
45
vendor/github.com/tetratelabs/wazero/experimental/sys/error.go
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package sys
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
)
|
||||
|
||||
// UnwrapOSError returns an Errno or zero if the input is nil.
|
||||
func UnwrapOSError(err error) Errno {
|
||||
if err == nil {
|
||||
return 0
|
||||
}
|
||||
err = underlyingError(err)
|
||||
switch err {
|
||||
case nil, io.EOF:
|
||||
return 0 // EOF is not a Errno
|
||||
case fs.ErrInvalid:
|
||||
return EINVAL
|
||||
case fs.ErrPermission:
|
||||
return EPERM
|
||||
case fs.ErrExist:
|
||||
return EEXIST
|
||||
case fs.ErrNotExist:
|
||||
return ENOENT
|
||||
case fs.ErrClosed:
|
||||
return EBADF
|
||||
}
|
||||
return errorToErrno(err)
|
||||
}
|
||||
|
||||
// underlyingError returns the underlying error if a well-known OS error type.
|
||||
//
|
||||
// This impl is basically the same as os.underlyingError in os/error.go
|
||||
func underlyingError(err error) error {
|
||||
switch err := err.(type) {
|
||||
case *os.PathError:
|
||||
return err.Err
|
||||
case *os.LinkError:
|
||||
return err.Err
|
||||
case *os.SyscallError:
|
||||
return err.Err
|
||||
}
|
||||
return err
|
||||
}
|
||||
316
vendor/github.com/tetratelabs/wazero/experimental/sys/file.go
generated
vendored
Normal file
316
vendor/github.com/tetratelabs/wazero/experimental/sys/file.go
generated
vendored
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
package sys
|
||||
|
||||
import "github.com/tetratelabs/wazero/sys"
|
||||
|
||||
// File is a writeable fs.File bridge backed by syscall functions needed for ABI
|
||||
// including WASI.
|
||||
//
|
||||
// Implementations should embed UnimplementedFile for forward compatibility. Any
|
||||
// unsupported method or parameter should return ENOSYS.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// All methods that can return an error return a Errno, which is zero
|
||||
// on success.
|
||||
//
|
||||
// Restricting to Errno matches current WebAssembly host functions,
|
||||
// which are constrained to well-known error codes. For example, WASI maps syscall
|
||||
// errors to u32 numeric values.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - You must call Close to avoid file resource conflicts. For example,
|
||||
// Windows cannot delete the underlying directory while a handle to it
|
||||
// remains open.
|
||||
// - A writable filesystem abstraction is not yet implemented as of Go 1.20.
|
||||
// See https://github.com/golang/go/issues/45757
|
||||
type File interface {
|
||||
// Dev returns the device ID (Stat_t.Dev) of this file, zero if unknown or
|
||||
// an error retrieving it.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// Possible errors are those from Stat, except ENOSYS should not
|
||||
// be returned. Zero should be returned if there is no implementation.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - Implementations should cache this result.
|
||||
// - This combined with Ino can implement os.SameFile.
|
||||
Dev() (uint64, Errno)
|
||||
|
||||
// Ino returns the serial number (Stat_t.Ino) of this file, zero if unknown
|
||||
// or an error retrieving it.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// Possible errors are those from Stat, except ENOSYS should not
|
||||
// be returned. Zero should be returned if there is no implementation.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - Implementations should cache this result.
|
||||
// - This combined with Dev can implement os.SameFile.
|
||||
Ino() (sys.Inode, Errno)
|
||||
|
||||
// IsDir returns true if this file is a directory or an error there was an
|
||||
// error retrieving this information.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// Possible errors are those from Stat, except ENOSYS should not
|
||||
// be returned. false should be returned if there is no implementation.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - Implementations should cache this result.
|
||||
IsDir() (bool, Errno)
|
||||
|
||||
// IsAppend returns true if the file was opened with O_APPEND, or
|
||||
// SetAppend was successfully enabled on this file.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This might not match the underlying state of the file descriptor if
|
||||
// the file was not opened via OpenFile.
|
||||
IsAppend() bool
|
||||
|
||||
// SetAppend toggles the append mode (O_APPEND) of this file.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - There is no `O_APPEND` for `fcntl` in POSIX, so implementations may
|
||||
// have to re-open the underlying file to apply this. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
|
||||
SetAppend(enable bool) Errno
|
||||
|
||||
// Stat is similar to syscall.Fstat.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Fstat and `fstatat` with `AT_FDCWD` in POSIX.
|
||||
// See https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
|
||||
// - A fs.FileInfo backed implementation sets atim, mtim and ctim to the
|
||||
// same value.
|
||||
// - Windows allows you to stat a closed directory.
|
||||
Stat() (sys.Stat_t, Errno)
|
||||
|
||||
// Read attempts to read all bytes in the file into `buf`, and returns the
|
||||
// count read even on error.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed or not readable.
|
||||
// - EISDIR: the file was a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like io.Reader and `read` in POSIX, preferring semantics of
|
||||
// io.Reader. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html
|
||||
// - Unlike io.Reader, there is no io.EOF returned on end-of-file. To
|
||||
// read the file completely, the caller must repeat until `n` is zero.
|
||||
Read(buf []byte) (n int, errno Errno)
|
||||
|
||||
// Pread attempts to read all bytes in the file into `p`, starting at the
|
||||
// offset `off`, and returns the count read even on error.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed or not readable.
|
||||
// - EINVAL: the offset was negative.
|
||||
// - EISDIR: the file was a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like io.ReaderAt and `pread` in POSIX, preferring semantics
|
||||
// of io.ReaderAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html
|
||||
// - Unlike io.ReaderAt, there is no io.EOF returned on end-of-file. To
|
||||
// read the file completely, the caller must repeat until `n` is zero.
|
||||
Pread(buf []byte, off int64) (n int, errno Errno)
|
||||
|
||||
// Seek attempts to set the next offset for Read or Write and returns the
|
||||
// resulting absolute offset or an error.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// The `offset` parameters is interpreted in terms of `whence`:
|
||||
// - io.SeekStart: relative to the start of the file, e.g. offset=0 sets
|
||||
// the next Read or Write to the beginning of the file.
|
||||
// - io.SeekCurrent: relative to the current offset, e.g. offset=16 sets
|
||||
// the next Read or Write 16 bytes past the prior.
|
||||
// - io.SeekEnd: relative to the end of the file, e.g. offset=-1 sets the
|
||||
// next Read or Write to the last byte in the file.
|
||||
//
|
||||
// # Behavior when a directory
|
||||
//
|
||||
// The only supported use case for a directory is seeking to `offset` zero
|
||||
// (`whence` = io.SeekStart). This should have the same behavior as
|
||||
// os.File, which resets any internal state used by Readdir.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed or not readable.
|
||||
// - EINVAL: the offset was negative.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like io.Seeker and `fseek` in POSIX, preferring semantics
|
||||
// of io.Seeker. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/fseek.html
|
||||
Seek(offset int64, whence int) (newOffset int64, errno Errno)
|
||||
|
||||
// Readdir reads the contents of the directory associated with file and
|
||||
// returns a slice of up to n Dirent values in an arbitrary order. This is
|
||||
// a stateful function, so subsequent calls return any next values.
|
||||
//
|
||||
// If n > 0, Readdir returns at most n entries or an error.
|
||||
// If n <= 0, Readdir returns all remaining entries or an error.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file was closed or not a directory.
|
||||
// - ENOENT: the directory could not be read (e.g. deleted).
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like `Readdir` on os.File, but unlike `readdir` in POSIX.
|
||||
// See https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html
|
||||
// - Unlike os.File, there is no io.EOF returned on end-of-directory. To
|
||||
// read the directory completely, the caller must repeat until the
|
||||
// count read (`len(dirents)`) is less than `n`.
|
||||
// - See /RATIONALE.md for design notes.
|
||||
Readdir(n int) (dirents []Dirent, errno Errno)
|
||||
|
||||
// Write attempts to write all bytes in `p` to the file, and returns the
|
||||
// count written even on error.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file was closed, not writeable, or a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like io.Writer and `write` in POSIX, preferring semantics of
|
||||
// io.Writer. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
|
||||
Write(buf []byte) (n int, errno Errno)
|
||||
|
||||
// Pwrite attempts to write all bytes in `p` to the file at the given
|
||||
// offset `off`, and returns the count written even on error.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed or not writeable.
|
||||
// - EINVAL: the offset was negative.
|
||||
// - EISDIR: the file was a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like io.WriterAt and `pwrite` in POSIX, preferring semantics
|
||||
// of io.WriterAt. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html
|
||||
Pwrite(buf []byte, off int64) (n int, errno Errno)
|
||||
|
||||
// Truncate truncates a file to a specified length.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed.
|
||||
// - EINVAL: the `size` is negative.
|
||||
// - EISDIR: the file was a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Ftruncate and `ftruncate` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
|
||||
// - Windows does not error when calling Truncate on a closed file.
|
||||
Truncate(size int64) Errno
|
||||
|
||||
// Sync synchronizes changes to the file.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - EBADF: the file or directory was closed.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Fsync and `fsync` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html
|
||||
// - This returns with no error instead of ENOSYS when
|
||||
// unimplemented. This prevents fake filesystems from erring.
|
||||
// - Windows does not error when calling Sync on a closed file.
|
||||
Sync() Errno
|
||||
|
||||
// Datasync synchronizes the data of a file.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - EBADF: the file or directory was closed.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Fdatasync and `fdatasync` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html
|
||||
// - This returns with no error instead of ENOSYS when
|
||||
// unimplemented. This prevents fake filesystems from erring.
|
||||
// - As this is commonly missing, some implementations dispatch to Sync.
|
||||
Datasync() Errno
|
||||
|
||||
// Utimens set file access and modification times of this file, at
|
||||
// nanosecond precision.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// The `atim` and `mtim` parameters refer to access and modification time
|
||||
// stamps as defined in sys.Stat_t. To retain one or the other, substitute
|
||||
// it with the pseudo-timestamp UTIME_OMIT.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EBADF: the file or directory was closed.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.UtimesNano and `futimens` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
|
||||
// - Windows requires files to be open with O_RDWR, which means you
|
||||
// cannot use this to update timestamps on a directory (EPERM).
|
||||
Utimens(atim, mtim int64) Errno
|
||||
|
||||
// Close closes the underlying file.
|
||||
//
|
||||
// A zero Errno is returned if unimplemented or success.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Close and `close` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
|
||||
Close() Errno
|
||||
}
|
||||
292
vendor/github.com/tetratelabs/wazero/experimental/sys/fs.go
generated
vendored
Normal file
292
vendor/github.com/tetratelabs/wazero/experimental/sys/fs.go
generated
vendored
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
package sys
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
|
||||
"github.com/tetratelabs/wazero/sys"
|
||||
)
|
||||
|
||||
// FS is a writeable fs.FS bridge backed by syscall functions needed for ABI
|
||||
// including WASI.
|
||||
//
|
||||
// Implementations should embed UnimplementedFS for forward compatibility. Any
|
||||
// unsupported method or parameter should return ENO
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// All methods that can return an error return a Errno, which is zero
|
||||
// on success.
|
||||
//
|
||||
// Restricting to Errno matches current WebAssembly host functions,
|
||||
// which are constrained to well-known error codes. For example, WASI maps syscall
|
||||
// errors to u32 numeric values.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// A writable filesystem abstraction is not yet implemented as of Go 1.20. See
|
||||
// https://github.com/golang/go/issues/45757
|
||||
type FS interface {
|
||||
// OpenFile opens a file. It should be closed via Close on File.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` or `flag` is invalid.
|
||||
// - EISDIR: the path was a directory, but flag included O_RDWR or
|
||||
// O_WRONLY
|
||||
// - ENOENT: `path` doesn't exist and `flag` doesn't contain O_CREAT.
|
||||
//
|
||||
// # Constraints on the returned file
|
||||
//
|
||||
// Implementations that can read flags should enforce them regardless of
|
||||
// the type returned. For example, while os.File implements io.Writer,
|
||||
// attempts to write to a directory or a file opened with O_RDONLY fail
|
||||
// with a EBADF.
|
||||
//
|
||||
// Some implementations choose whether to enforce read-only opens, namely
|
||||
// fs.FS. While fs.FS is supported (Adapt), wazero cannot runtime enforce
|
||||
// open flags. Instead, we encourage good behavior and test our built-in
|
||||
// implementations.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like os.OpenFile, except the path is relative to this file
|
||||
// system, and Errno is returned instead of os.PathError.
|
||||
// - Implications of permissions when O_CREAT are described in Chmod notes.
|
||||
// - This is like `open` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
|
||||
OpenFile(path string, flag Oflag, perm fs.FileMode) (File, Errno)
|
||||
|
||||
// Lstat gets file status without following symbolic links.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - ENOENT: `path` doesn't exist.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Lstat, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `lstat` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html
|
||||
// - An fs.FileInfo backed implementation sets atim, mtim and ctim to the
|
||||
// same value.
|
||||
// - When the path is a symbolic link, the stat returned is for the link,
|
||||
// not the file it refers to.
|
||||
Lstat(path string) (sys.Stat_t, Errno)
|
||||
|
||||
// Stat gets file status.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - ENOENT: `path` doesn't exist.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Stat, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `stat` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
|
||||
// - An fs.FileInfo backed implementation sets atim, mtim and ctim to the
|
||||
// same value.
|
||||
// - When the path is a symbolic link, the stat returned is for the file
|
||||
// it refers to.
|
||||
Stat(path string) (sys.Stat_t, Errno)
|
||||
|
||||
// Mkdir makes a directory.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
// - EEXIST: `path` exists and is a directory.
|
||||
// - ENOTDIR: `path` exists and is a file.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Mkdir, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `mkdir` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html
|
||||
// - Implications of permissions are described in Chmod notes.
|
||||
Mkdir(path string, perm fs.FileMode) Errno
|
||||
|
||||
// Chmod changes the mode of the file.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
// - ENOENT: `path` does not exist.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Chmod, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `chmod` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html
|
||||
// - Windows ignores the execute bit, and any permissions come back as
|
||||
// group and world. For example, chmod of 0400 reads back as 0444, and
|
||||
// 0700 0666. Also, permissions on directories aren't supported at all.
|
||||
Chmod(path string, perm fs.FileMode) Errno
|
||||
|
||||
// Rename renames file or directory.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `from` or `to` is invalid.
|
||||
// - ENOENT: `from` or `to` don't exist.
|
||||
// - ENOTDIR: `from` is a directory and `to` exists as a file.
|
||||
// - EISDIR: `from` is a file and `to` exists as a directory.
|
||||
// - ENOTEMPTY: `both from` and `to` are existing directory, but
|
||||
// `to` is not empty.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Rename, except the paths are relative to this
|
||||
// file system.
|
||||
// - This is like `rename` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html
|
||||
// - Windows doesn't let you overwrite an existing directory.
|
||||
Rename(from, to string) Errno
|
||||
|
||||
// Rmdir removes a directory.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
// - ENOENT: `path` doesn't exist.
|
||||
// - ENOTDIR: `path` exists, but isn't a directory.
|
||||
// - ENOTEMPTY: `path` exists, but isn't empty.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Rmdir, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `rmdir` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html
|
||||
// - As of Go 1.19, Windows maps ENOTDIR to ENOENT.
|
||||
Rmdir(path string) Errno
|
||||
|
||||
// Unlink removes a directory entry.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
// - ENOENT: `path` doesn't exist.
|
||||
// - EISDIR: `path` exists, but is a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Unlink, except the `path` is relative to this
|
||||
// file system.
|
||||
// - This is like `unlink` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html
|
||||
// - On Windows, syscall.Unlink doesn't delete symlink to directory unlike other platforms. Implementations might
|
||||
// want to combine syscall.RemoveDirectory with syscall.Unlink in order to delete such links on Windows.
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectorya
|
||||
Unlink(path string) Errno
|
||||
|
||||
// Link creates a "hard" link from oldPath to newPath, in contrast to a
|
||||
// soft link (via Symlink).
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EPERM: `oldPath` is invalid.
|
||||
// - ENOENT: `oldPath` doesn't exist.
|
||||
// - EISDIR: `newPath` exists, but is a directory.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Link, except the `oldPath` is relative to this
|
||||
// file system.
|
||||
// - This is like `link` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html
|
||||
Link(oldPath, newPath string) Errno
|
||||
|
||||
// Symlink creates a "soft" link from oldPath to newPath, in contrast to a
|
||||
// hard link (via Link).
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EPERM: `oldPath` or `newPath` is invalid.
|
||||
// - EEXIST: `newPath` exists.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Symlink, except the `oldPath` is relative to
|
||||
// this file system.
|
||||
// - This is like `symlink` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html
|
||||
// - Only `newPath` is relative to this file system and `oldPath` is kept
|
||||
// as-is. That is because the link is only resolved relative to the
|
||||
// directory when dereferencing it (e.g. ReadLink).
|
||||
// See https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409
|
||||
// for how others implement this.
|
||||
// - Symlinks in Windows requires `SeCreateSymbolicLinkPrivilege`.
|
||||
// Otherwise, EPERM results.
|
||||
// See https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/create-symbolic-links
|
||||
Symlink(oldPath, linkName string) Errno
|
||||
|
||||
// Readlink reads the contents of a symbolic link.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.Readlink, except the path is relative to this
|
||||
// filesystem.
|
||||
// - This is like `readlink` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html
|
||||
// - On Windows, the path separator is different from other platforms,
|
||||
// but to provide consistent results to Wasm, this normalizes to a "/"
|
||||
// separator.
|
||||
Readlink(path string) (string, Errno)
|
||||
|
||||
// Utimens set file access and modification times on a path relative to
|
||||
// this file system, at nanosecond precision.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// If the path is a symbolic link, the target of expanding that link is
|
||||
// updated.
|
||||
//
|
||||
// The `atim` and `mtim` parameters refer to access and modification time
|
||||
// stamps as defined in sys.Stat_t. To retain one or the other, substitute
|
||||
// it with the pseudo-timestamp UTIME_OMIT.
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// A zero Errno is success. The below are expected otherwise:
|
||||
// - ENOSYS: the implementation does not support this function.
|
||||
// - EINVAL: `path` is invalid.
|
||||
// - EEXIST: `path` exists and is a directory.
|
||||
// - ENOTDIR: `path` exists and is a file.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is like syscall.UtimesNano and `utimensat` with `AT_FDCWD` in
|
||||
// POSIX. See https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
|
||||
Utimens(path string, atim, mtim int64) Errno
|
||||
}
|
||||
70
vendor/github.com/tetratelabs/wazero/experimental/sys/oflag.go
generated
vendored
Normal file
70
vendor/github.com/tetratelabs/wazero/experimental/sys/oflag.go
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package sys
|
||||
|
||||
// Oflag are flags used for FS.OpenFile. Values, including zero, should not be
|
||||
// interpreted numerically. Instead, use by constants prefixed with 'O_' with
|
||||
// special casing noted below.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - O_RDONLY, O_RDWR and O_WRONLY are mutually exclusive, while the other
|
||||
// flags can coexist bitwise.
|
||||
// - This is like `flag` in os.OpenFile and `oflag` in POSIX. See
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
|
||||
type Oflag uint32
|
||||
|
||||
// This is a subset of oflags to reduce implementation burden. `wasip1` splits
|
||||
// these across `oflags` and `fdflags`. We can't rely on the Go `os` package,
|
||||
// as it is missing some values. Any flags added will be defined in POSIX
|
||||
// order, as needed by functions that explicitly document accepting them.
|
||||
//
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-oflags-flagsu16
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-fdflags-flagsu16
|
||||
const (
|
||||
// O_RDONLY is like os.O_RDONLY
|
||||
O_RDONLY Oflag = iota
|
||||
|
||||
// O_RDWR is like os.O_RDWR
|
||||
O_RDWR
|
||||
|
||||
// O_WRONLY is like os.O_WRONLY
|
||||
O_WRONLY
|
||||
|
||||
// Define bitflags as they are in POSIX `open`: alphabetically
|
||||
|
||||
// O_APPEND is like os.O_APPEND
|
||||
O_APPEND Oflag = 1 << iota
|
||||
|
||||
// O_CREAT is link os.O_CREATE
|
||||
O_CREAT
|
||||
|
||||
// O_DIRECTORY is defined on some platforms as syscall.O_DIRECTORY.
|
||||
//
|
||||
// Note: This ensures that the opened file is a directory. Those emulating
|
||||
// on platforms that don't support the O_DIRECTORY, can double-check the
|
||||
// result with File.IsDir (or stat) and err if not a directory.
|
||||
O_DIRECTORY
|
||||
|
||||
// O_DSYNC is defined on some platforms as syscall.O_DSYNC.
|
||||
O_DSYNC
|
||||
|
||||
// O_EXCL is defined on some platforms as syscall.O_EXCL.
|
||||
O_EXCL
|
||||
|
||||
// O_NOFOLLOW is defined on some platforms as syscall.O_NOFOLLOW.
|
||||
//
|
||||
// Note: This allows programs to ensure that if the opened file is a
|
||||
// symbolic link, the link itself is opened instead of its target.
|
||||
O_NOFOLLOW
|
||||
|
||||
// O_NONBLOCK is defined on some platforms as syscall.O_NONBLOCK.
|
||||
O_NONBLOCK
|
||||
|
||||
// O_RSYNC is defined on some platforms as syscall.O_RSYNC.
|
||||
O_RSYNC
|
||||
|
||||
// O_SYNC is defined on some platforms as syscall.O_SYNC.
|
||||
O_SYNC
|
||||
|
||||
// O_TRUNC is defined on some platforms as syscall.O_TRUNC.
|
||||
O_TRUNC
|
||||
)
|
||||
106
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go
generated
vendored
Normal file
106
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno.go
generated
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//go:build !plan9 && !aix
|
||||
|
||||
package sys
|
||||
|
||||
import "syscall"
|
||||
|
||||
func syscallToErrno(err error) (Errno, bool) {
|
||||
errno, ok := err.(syscall.Errno)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
switch errno {
|
||||
case 0:
|
||||
return 0, true
|
||||
case syscall.EACCES:
|
||||
return EACCES, true
|
||||
case syscall.EAGAIN:
|
||||
return EAGAIN, true
|
||||
case syscall.EBADF:
|
||||
return EBADF, true
|
||||
case syscall.EEXIST:
|
||||
return EEXIST, true
|
||||
case syscall.EFAULT:
|
||||
return EFAULT, true
|
||||
case syscall.EINTR:
|
||||
return EINTR, true
|
||||
case syscall.EINVAL:
|
||||
return EINVAL, true
|
||||
case syscall.EIO:
|
||||
return EIO, true
|
||||
case syscall.EISDIR:
|
||||
return EISDIR, true
|
||||
case syscall.ELOOP:
|
||||
return ELOOP, true
|
||||
case syscall.ENAMETOOLONG:
|
||||
return ENAMETOOLONG, true
|
||||
case syscall.ENOENT:
|
||||
return ENOENT, true
|
||||
case syscall.ENOSYS:
|
||||
return ENOSYS, true
|
||||
case syscall.ENOTDIR:
|
||||
return ENOTDIR, true
|
||||
case syscall.ERANGE:
|
||||
return ERANGE, true
|
||||
case syscall.ENOTEMPTY:
|
||||
return ENOTEMPTY, true
|
||||
case syscall.ENOTSOCK:
|
||||
return ENOTSOCK, true
|
||||
case syscall.ENOTSUP:
|
||||
return ENOTSUP, true
|
||||
case syscall.EPERM:
|
||||
return EPERM, true
|
||||
case syscall.EROFS:
|
||||
return EROFS, true
|
||||
default:
|
||||
return EIO, true
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrap is a convenience for runtime.GOOS which define syscall.Errno.
|
||||
func (e Errno) Unwrap() error {
|
||||
switch e {
|
||||
case 0:
|
||||
return nil
|
||||
case EACCES:
|
||||
return syscall.EACCES
|
||||
case EAGAIN:
|
||||
return syscall.EAGAIN
|
||||
case EBADF:
|
||||
return syscall.EBADF
|
||||
case EEXIST:
|
||||
return syscall.EEXIST
|
||||
case EFAULT:
|
||||
return syscall.EFAULT
|
||||
case EINTR:
|
||||
return syscall.EINTR
|
||||
case EINVAL:
|
||||
return syscall.EINVAL
|
||||
case EIO:
|
||||
return syscall.EIO
|
||||
case EISDIR:
|
||||
return syscall.EISDIR
|
||||
case ELOOP:
|
||||
return syscall.ELOOP
|
||||
case ENAMETOOLONG:
|
||||
return syscall.ENAMETOOLONG
|
||||
case ENOENT:
|
||||
return syscall.ENOENT
|
||||
case ENOSYS:
|
||||
return syscall.ENOSYS
|
||||
case ENOTDIR:
|
||||
return syscall.ENOTDIR
|
||||
case ENOTEMPTY:
|
||||
return syscall.ENOTEMPTY
|
||||
case ENOTSOCK:
|
||||
return syscall.ENOTSOCK
|
||||
case ENOTSUP:
|
||||
return syscall.ENOTSUP
|
||||
case EPERM:
|
||||
return syscall.EPERM
|
||||
case EROFS:
|
||||
return syscall.EROFS
|
||||
default:
|
||||
return syscall.EIO
|
||||
}
|
||||
}
|
||||
13
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go
generated
vendored
Normal file
13
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_notwindows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//go:build !windows
|
||||
|
||||
package sys
|
||||
|
||||
func errorToErrno(err error) Errno {
|
||||
if errno, ok := err.(Errno); ok {
|
||||
return errno
|
||||
}
|
||||
if errno, ok := syscallToErrno(err); ok {
|
||||
return errno
|
||||
}
|
||||
return EIO
|
||||
}
|
||||
7
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_unsupported.go
generated
vendored
Normal file
7
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_unsupported.go
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
//go:build plan9 || aix
|
||||
|
||||
package sys
|
||||
|
||||
func syscallToErrno(err error) (Errno, bool) {
|
||||
return 0, false
|
||||
}
|
||||
62
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go
generated
vendored
Normal file
62
vendor/github.com/tetratelabs/wazero/experimental/sys/syscall_errno_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package sys
|
||||
|
||||
import "syscall"
|
||||
|
||||
// These are errors not defined in the syscall package. They are prefixed with
|
||||
// underscore to avoid exporting them.
|
||||
//
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
|
||||
const (
|
||||
// _ERROR_INVALID_HANDLE is a Windows error returned by syscall.Write
|
||||
// instead of syscall.EBADF
|
||||
_ERROR_INVALID_HANDLE = syscall.Errno(6)
|
||||
|
||||
// _ERROR_INVALID_NAME is a Windows error returned by open when a file
|
||||
// path has a trailing slash
|
||||
_ERROR_INVALID_NAME = syscall.Errno(0x7B)
|
||||
|
||||
// _ERROR_NEGATIVE_SEEK is a Windows error returned by os.Truncate
|
||||
// instead of syscall.EINVAL
|
||||
_ERROR_NEGATIVE_SEEK = syscall.Errno(0x83)
|
||||
|
||||
// _ERROR_DIRECTORY is a Windows error returned by syscall.Rmdir
|
||||
// instead of syscall.ENOTDIR
|
||||
_ERROR_DIRECTORY = syscall.Errno(0x10B)
|
||||
|
||||
// _ERROR_INVALID_SOCKET is a Windows error returned by winsock_select
|
||||
// when a given handle is not a socket.
|
||||
_ERROR_INVALID_SOCKET = syscall.Errno(0x2736)
|
||||
)
|
||||
|
||||
func errorToErrno(err error) Errno {
|
||||
switch err := err.(type) {
|
||||
case Errno:
|
||||
return err
|
||||
case syscall.Errno:
|
||||
// Note: In windows, _ERROR_PATH_NOT_FOUND(0x3) maps to syscall.ENOTDIR
|
||||
switch err {
|
||||
case syscall.ERROR_ALREADY_EXISTS:
|
||||
return EEXIST
|
||||
case _ERROR_DIRECTORY:
|
||||
return ENOTDIR
|
||||
case syscall.ERROR_DIR_NOT_EMPTY:
|
||||
return ENOTEMPTY
|
||||
case syscall.ERROR_FILE_EXISTS:
|
||||
return EEXIST
|
||||
case _ERROR_INVALID_HANDLE, _ERROR_INVALID_SOCKET:
|
||||
return EBADF
|
||||
case syscall.ERROR_ACCESS_DENIED:
|
||||
// POSIX read and write functions expect EBADF, not EACCES when not
|
||||
// open for reading or writing.
|
||||
return EBADF
|
||||
case syscall.ERROR_PRIVILEGE_NOT_HELD:
|
||||
return EPERM
|
||||
case _ERROR_NEGATIVE_SEEK, _ERROR_INVALID_NAME:
|
||||
return EINVAL
|
||||
}
|
||||
errno, _ := syscallToErrno(err)
|
||||
return errno
|
||||
default:
|
||||
return EIO
|
||||
}
|
||||
}
|
||||
10
vendor/github.com/tetratelabs/wazero/experimental/sys/time.go
generated
vendored
Normal file
10
vendor/github.com/tetratelabs/wazero/experimental/sys/time.go
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package sys
|
||||
|
||||
import "math"
|
||||
|
||||
// UTIME_OMIT is a special constant for use in updating times via FS.Utimens
|
||||
// or File.Utimens. When used for atim or mtim, the value is retained.
|
||||
//
|
||||
// Note: This may be implemented via a stat when the underlying filesystem
|
||||
// does not support this value.
|
||||
const UTIME_OMIT int64 = math.MinInt64
|
||||
160
vendor/github.com/tetratelabs/wazero/experimental/sys/unimplemented.go
generated
vendored
Normal file
160
vendor/github.com/tetratelabs/wazero/experimental/sys/unimplemented.go
generated
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
package sys
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
|
||||
"github.com/tetratelabs/wazero/sys"
|
||||
)
|
||||
|
||||
// UnimplementedFS is an FS that returns ENOSYS for all functions,
|
||||
// This should be embedded to have forward compatible implementations.
|
||||
type UnimplementedFS struct{}
|
||||
|
||||
// OpenFile implements FS.OpenFile
|
||||
func (UnimplementedFS) OpenFile(path string, flag Oflag, perm fs.FileMode) (File, Errno) {
|
||||
return nil, ENOSYS
|
||||
}
|
||||
|
||||
// Lstat implements FS.Lstat
|
||||
func (UnimplementedFS) Lstat(path string) (sys.Stat_t, Errno) {
|
||||
return sys.Stat_t{}, ENOSYS
|
||||
}
|
||||
|
||||
// Stat implements FS.Stat
|
||||
func (UnimplementedFS) Stat(path string) (sys.Stat_t, Errno) {
|
||||
return sys.Stat_t{}, ENOSYS
|
||||
}
|
||||
|
||||
// Readlink implements FS.Readlink
|
||||
func (UnimplementedFS) Readlink(path string) (string, Errno) {
|
||||
return "", ENOSYS
|
||||
}
|
||||
|
||||
// Mkdir implements FS.Mkdir
|
||||
func (UnimplementedFS) Mkdir(path string, perm fs.FileMode) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Chmod implements FS.Chmod
|
||||
func (UnimplementedFS) Chmod(path string, perm fs.FileMode) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Rename implements FS.Rename
|
||||
func (UnimplementedFS) Rename(from, to string) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Rmdir implements FS.Rmdir
|
||||
func (UnimplementedFS) Rmdir(path string) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Link implements FS.Link
|
||||
func (UnimplementedFS) Link(_, _ string) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Symlink implements FS.Symlink
|
||||
func (UnimplementedFS) Symlink(_, _ string) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Unlink implements FS.Unlink
|
||||
func (UnimplementedFS) Unlink(path string) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Utimens implements FS.Utimens
|
||||
func (UnimplementedFS) Utimens(path string, atim, mtim int64) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// UnimplementedFile is a File that returns ENOSYS for all functions,
|
||||
// except where no-op are otherwise documented.
|
||||
//
|
||||
// This should be embedded to have forward compatible implementations.
|
||||
type UnimplementedFile struct{}
|
||||
|
||||
// Dev implements File.Dev
|
||||
func (UnimplementedFile) Dev() (uint64, Errno) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// Ino implements File.Ino
|
||||
func (UnimplementedFile) Ino() (sys.Inode, Errno) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// IsDir implements File.IsDir
|
||||
func (UnimplementedFile) IsDir() (bool, Errno) {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
// IsAppend implements File.IsAppend
|
||||
func (UnimplementedFile) IsAppend() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SetAppend implements File.SetAppend
|
||||
func (UnimplementedFile) SetAppend(bool) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Stat implements File.Stat
|
||||
func (UnimplementedFile) Stat() (sys.Stat_t, Errno) {
|
||||
return sys.Stat_t{}, ENOSYS
|
||||
}
|
||||
|
||||
// Read implements File.Read
|
||||
func (UnimplementedFile) Read([]byte) (int, Errno) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
// Pread implements File.Pread
|
||||
func (UnimplementedFile) Pread([]byte, int64) (int, Errno) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
// Seek implements File.Seek
|
||||
func (UnimplementedFile) Seek(int64, int) (int64, Errno) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
// Readdir implements File.Readdir
|
||||
func (UnimplementedFile) Readdir(int) (dirents []Dirent, errno Errno) {
|
||||
return nil, ENOSYS
|
||||
}
|
||||
|
||||
// Write implements File.Write
|
||||
func (UnimplementedFile) Write([]byte) (int, Errno) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
// Pwrite implements File.Pwrite
|
||||
func (UnimplementedFile) Pwrite([]byte, int64) (int, Errno) {
|
||||
return 0, ENOSYS
|
||||
}
|
||||
|
||||
// Truncate implements File.Truncate
|
||||
func (UnimplementedFile) Truncate(int64) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Sync implements File.Sync
|
||||
func (UnimplementedFile) Sync() Errno {
|
||||
return 0 // not ENOSYS
|
||||
}
|
||||
|
||||
// Datasync implements File.Datasync
|
||||
func (UnimplementedFile) Datasync() Errno {
|
||||
return 0 // not ENOSYS
|
||||
}
|
||||
|
||||
// Utimens implements File.Utimens
|
||||
func (UnimplementedFile) Utimens(int64, int64) Errno {
|
||||
return ENOSYS
|
||||
}
|
||||
|
||||
// Close implements File.Close
|
||||
func (UnimplementedFile) Close() (errno Errno) { return }
|
||||
Loading…
Add table
Add a link
Reference in a new issue