mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] support processing of (many) more media types (#3090)
* initial work replacing our media decoding / encoding pipeline with ffprobe + ffmpeg * specify the video codec to use when generating static image from emoji * update go-storage library (fixes incompatibility after updating go-iotools) * maintain image aspect ratio when generating a thumbnail for it * update readme to show go-ffmpreg * fix a bunch of media tests, move filesize checking to callers of media manager for more flexibility * remove extra debug from error message * fix up incorrect function signatures * update PutFile to just use regular file copy, as changes are file is on separate partition * fix remaining tests, remove some unneeded tests now we're working with ffmpeg/ffprobe * update more tests, add more code comments * add utilities to generate processed emoji / media outputs * fix remaining tests * add test for opus media file, add license header to utility cmds * limit the number of concurrently available ffmpeg / ffprobe instances * reduce number of instances * further reduce number of instances * fix envparsing test with configuration variables * update docs and configuration with new media-{local,remote}-max-size variables
This commit is contained in:
97
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go
generated
vendored
Normal file
97
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/args.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// argsGet is the WASI function named ArgsGetName that reads command-line
|
||||
// argument data.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - argv: offset to begin writing argument offsets in uint32 little-endian
|
||||
// encoding to api.Memory
|
||||
// - argsSizesGet result argc * 4 bytes are written to this offset
|
||||
// - argvBuf: offset to write the null terminated arguments to api.Memory
|
||||
// - argsSizesGet result argv_len bytes are written to this offset
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is ErrnoSuccess except the following error conditions:
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if argsSizesGet wrote argc=2 and argvLen=5 for arguments:
|
||||
// "a" and "bc" parameters argv=7 and argvBuf=1, this function writes the below
|
||||
// to api.Memory:
|
||||
//
|
||||
// argvLen uint32le uint32le
|
||||
// +----------------+ +--------+ +--------+
|
||||
// | | | | | |
|
||||
// []byte{?, 'a', 0, 'b', 'c', 0, ?, 1, 0, 0, 0, 3, 0, 0, 0, ?}
|
||||
// argvBuf --^ ^ ^
|
||||
// argv --| |
|
||||
// offset that begins "a" --+ |
|
||||
// offset that begins "bc" --+
|
||||
//
|
||||
// See argsSizesGet
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_get
|
||||
// See https://en.wikipedia.org/wiki/Null-terminated_string
|
||||
var argsGet = newHostFunc(wasip1.ArgsGetName, argsGetFn, []api.ValueType{i32, i32}, "argv", "argv_buf")
|
||||
|
||||
func argsGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
argv, argvBuf := uint32(params[0]), uint32(params[1])
|
||||
return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Args(), argv, argvBuf, sysCtx.ArgsSize())
|
||||
}
|
||||
|
||||
// argsSizesGet is the WASI function named ArgsSizesGetName that reads
|
||||
// command-line argument sizes.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - resultArgc: offset to write the argument count to api.Memory
|
||||
// - resultArgvLen: offset to write the null-terminated argument length to
|
||||
// api.Memory
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is ErrnoSuccess except the following error conditions:
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if args are "a", "bc" and parameters resultArgc=1 and
|
||||
// resultArgvLen=6, this function writes the below to api.Memory:
|
||||
//
|
||||
// uint32le uint32le
|
||||
// +--------+ +--------+
|
||||
// | | | |
|
||||
// []byte{?, 2, 0, 0, 0, ?, 5, 0, 0, 0, ?}
|
||||
// resultArgc --^ ^
|
||||
// 2 args --+ |
|
||||
// resultArgvLen --|
|
||||
// len([]byte{'a',0,'b',c',0}) --+
|
||||
//
|
||||
// See argsGet
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#args_sizes_get
|
||||
// See https://en.wikipedia.org/wiki/Null-terminated_string
|
||||
var argsSizesGet = newHostFunc(wasip1.ArgsSizesGetName, argsSizesGetFn, []api.ValueType{i32, i32}, "result.argc", "result.argv_len")
|
||||
|
||||
func argsSizesGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
mem := mod.Memory()
|
||||
resultArgc, resultArgvLen := uint32(params[0]), uint32(params[1])
|
||||
|
||||
// argc and argv_len offsets are not necessarily sequential, so we have to
|
||||
// write them independently.
|
||||
if !mem.WriteUint32Le(resultArgc, uint32(len(sysCtx.Args()))) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
if !mem.WriteUint32Le(resultArgvLen, sysCtx.ArgsSize()) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
return 0
|
||||
}
|
116
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go
generated
vendored
Normal file
116
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/clock.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// clockResGet is the WASI function named ClockResGetName that returns the
|
||||
// resolution of time values returned by clockTimeGet.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - id: clock ID to use
|
||||
// - resultResolution: offset to write the resolution to api.Memory
|
||||
// - the resolution is an uint64 little-endian encoding
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is 0 except the following error conditions:
|
||||
// - sys.ENOTSUP: the clock ID is not supported.
|
||||
// - sys.EINVAL: the clock ID is invalid.
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if the resolution is 100ns, this function writes the below to
|
||||
// api.Memory:
|
||||
//
|
||||
// uint64le
|
||||
// +-------------------------------------+
|
||||
// | |
|
||||
// []byte{?, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ?}
|
||||
// resultResolution --^
|
||||
//
|
||||
// Note: This is similar to `clock_getres` in POSIX.
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_res_getid-clockid---errno-timestamp
|
||||
// See https://linux.die.net/man/3/clock_getres
|
||||
var clockResGet = newHostFunc(wasip1.ClockResGetName, clockResGetFn, []api.ValueType{i32, i32}, "id", "result.resolution")
|
||||
|
||||
func clockResGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
id, resultResolution := uint32(params[0]), uint32(params[1])
|
||||
|
||||
var resolution uint64 // ns
|
||||
switch id {
|
||||
case wasip1.ClockIDRealtime:
|
||||
resolution = uint64(sysCtx.WalltimeResolution())
|
||||
case wasip1.ClockIDMonotonic:
|
||||
resolution = uint64(sysCtx.NanotimeResolution())
|
||||
default:
|
||||
return sys.EINVAL
|
||||
}
|
||||
|
||||
if !mod.Memory().WriteUint64Le(resultResolution, resolution) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// clockTimeGet is the WASI function named ClockTimeGetName that returns
|
||||
// the time value of a name (time.Now).
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - id: clock ID to use
|
||||
// - precision: maximum lag (exclusive) that the returned time value may have,
|
||||
// compared to its actual value
|
||||
// - resultTimestamp: offset to write the timestamp to api.Memory
|
||||
// - the timestamp is epoch nanos encoded as a little-endian uint64
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is 0 except the following error conditions:
|
||||
// - sys.ENOTSUP: the clock ID is not supported.
|
||||
// - sys.EINVAL: the clock ID is invalid.
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if time.Now returned exactly midnight UTC 2022-01-01
|
||||
// (1640995200000000000), and parameters resultTimestamp=1, this function
|
||||
// writes the below to api.Memory:
|
||||
//
|
||||
// uint64le
|
||||
// +------------------------------------------+
|
||||
// | |
|
||||
// []byte{?, 0x0, 0x0, 0x1f, 0xa6, 0x70, 0xfc, 0xc5, 0x16, ?}
|
||||
// resultTimestamp --^
|
||||
//
|
||||
// Note: This is similar to `clock_gettime` in POSIX.
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clock_time_getid-clockid-precision-timestamp---errno-timestamp
|
||||
// See https://linux.die.net/man/3/clock_gettime
|
||||
var clockTimeGet = newHostFunc(wasip1.ClockTimeGetName, clockTimeGetFn, []api.ValueType{i32, i64, i32}, "id", "precision", "result.timestamp")
|
||||
|
||||
func clockTimeGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
id := uint32(params[0])
|
||||
// TODO: precision is currently ignored.
|
||||
// precision = params[1]
|
||||
resultTimestamp := uint32(params[2])
|
||||
|
||||
var val int64
|
||||
switch id {
|
||||
case wasip1.ClockIDRealtime:
|
||||
val = sysCtx.WalltimeNanos()
|
||||
case wasip1.ClockIDMonotonic:
|
||||
val = sysCtx.Nanotime()
|
||||
default:
|
||||
return sys.EINVAL
|
||||
}
|
||||
|
||||
if !mod.Memory().WriteUint64Le(resultTimestamp, uint64(val)) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
return 0
|
||||
}
|
100
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go
generated
vendored
Normal file
100
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/environ.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// environGet is the WASI function named EnvironGetName that reads
|
||||
// environment variables.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - environ: offset to begin writing environment offsets in uint32
|
||||
// little-endian encoding to api.Memory
|
||||
// - environSizesGet result environc * 4 bytes are written to this offset
|
||||
// - environBuf: offset to write the null-terminated variables to api.Memory
|
||||
// - the format is like os.Environ: null-terminated "key=val" entries
|
||||
// - environSizesGet result environLen bytes are written to this offset
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is 0 except the following error conditions:
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if environSizesGet wrote environc=2 and environLen=9 for
|
||||
// environment variables: "a=b", "b=cd" and parameters environ=11 and
|
||||
// environBuf=1, this function writes the below to api.Memory:
|
||||
//
|
||||
// environLen uint32le uint32le
|
||||
// +------------------------------------+ +--------+ +--------+
|
||||
// | | | | | |
|
||||
// []byte{?, 'a', '=', 'b', 0, 'b', '=', 'c', 'd', 0, ?, 1, 0, 0, 0, 5, 0, 0, 0, ?}
|
||||
// environBuf --^ ^ ^
|
||||
// environ offset for "a=b" --+ |
|
||||
// environ offset for "b=cd" --+
|
||||
//
|
||||
// See environSizesGet
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_get
|
||||
// See https://en.wikipedia.org/wiki/Null-terminated_string
|
||||
var environGet = newHostFunc(wasip1.EnvironGetName, environGetFn, []api.ValueType{i32, i32}, "environ", "environ_buf")
|
||||
|
||||
func environGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
environ, environBuf := uint32(params[0]), uint32(params[1])
|
||||
|
||||
return writeOffsetsAndNullTerminatedValues(mod.Memory(), sysCtx.Environ(), environ, environBuf, sysCtx.EnvironSize())
|
||||
}
|
||||
|
||||
// environSizesGet is the WASI function named EnvironSizesGetName that
|
||||
// reads environment variable sizes.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - resultEnvironc: offset to write the count of environment variables to
|
||||
// api.Memory
|
||||
// - resultEnvironvLen: offset to write the null-terminated environment
|
||||
// variable length to api.Memory
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is 0 except the following error conditions:
|
||||
// - sys.EFAULT: there is not enough memory to write results
|
||||
//
|
||||
// For example, if environ are "a=b","b=cd" and parameters resultEnvironc=1 and
|
||||
// resultEnvironvLen=6, this function writes the below to api.Memory:
|
||||
//
|
||||
// uint32le uint32le
|
||||
// +--------+ +--------+
|
||||
// | | | |
|
||||
// []byte{?, 2, 0, 0, 0, ?, 9, 0, 0, 0, ?}
|
||||
// resultEnvironc --^ ^
|
||||
// 2 variables --+ |
|
||||
// resultEnvironvLen --|
|
||||
// len([]byte{'a','=','b',0, |
|
||||
// 'b','=','c','d',0}) --+
|
||||
//
|
||||
// See environGet
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#environ_sizes_get
|
||||
// and https://en.wikipedia.org/wiki/Null-terminated_string
|
||||
var environSizesGet = newHostFunc(wasip1.EnvironSizesGetName, environSizesGetFn, []api.ValueType{i32, i32}, "result.environc", "result.environv_len")
|
||||
|
||||
func environSizesGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
mem := mod.Memory()
|
||||
resultEnvironc, resultEnvironvLen := uint32(params[0]), uint32(params[1])
|
||||
|
||||
// environc and environv_len offsets are not necessarily sequential, so we
|
||||
// have to write them independently.
|
||||
if !mem.WriteUint32Le(resultEnvironc, uint32(len(sysCtx.Environ()))) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
if !mem.WriteUint32Le(resultEnvironvLen, sysCtx.EnvironSize()) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
return 0
|
||||
}
|
2016
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go
generated
vendored
Normal file
2016
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/fs.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
239
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go
generated
vendored
Normal file
239
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/poll.go
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/fsapi"
|
||||
internalsys "github.com/tetratelabs/wazero/internal/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// pollOneoff is the WASI function named PollOneoffName that concurrently
|
||||
// polls for the occurrence of a set of events.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - in: pointer to the subscriptions (48 bytes each)
|
||||
// - out: pointer to the resulting events (32 bytes each)
|
||||
// - nsubscriptions: count of subscriptions, zero returns sys.EINVAL.
|
||||
// - resultNevents: count of events.
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is 0 except the following error conditions:
|
||||
// - sys.EINVAL: the parameters are invalid
|
||||
// - sys.ENOTSUP: a parameters is valid, but not yet supported.
|
||||
// - sys.EFAULT: there is not enough memory to read the subscriptions or
|
||||
// write results.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - Since the `out` pointer nests Errno, the result is always 0.
|
||||
// - This is similar to `poll` in POSIX.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#poll_oneoff
|
||||
// See https://linux.die.net/man/3/poll
|
||||
var pollOneoff = newHostFunc(
|
||||
wasip1.PollOneoffName, pollOneoffFn,
|
||||
[]api.ValueType{i32, i32, i32, i32},
|
||||
"in", "out", "nsubscriptions", "result.nevents",
|
||||
)
|
||||
|
||||
type event struct {
|
||||
eventType byte
|
||||
userData []byte
|
||||
errno wasip1.Errno
|
||||
}
|
||||
|
||||
func pollOneoffFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
in := uint32(params[0])
|
||||
out := uint32(params[1])
|
||||
nsubscriptions := uint32(params[2])
|
||||
resultNevents := uint32(params[3])
|
||||
|
||||
if nsubscriptions == 0 {
|
||||
return sys.EINVAL
|
||||
}
|
||||
|
||||
mem := mod.Memory()
|
||||
|
||||
// Ensure capacity prior to the read loop to reduce error handling.
|
||||
inBuf, ok := mem.Read(in, nsubscriptions*48)
|
||||
if !ok {
|
||||
return sys.EFAULT
|
||||
}
|
||||
outBuf, ok := mem.Read(out, nsubscriptions*32)
|
||||
// zero-out all buffer before writing
|
||||
for i := range outBuf {
|
||||
outBuf[i] = 0
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return sys.EFAULT
|
||||
}
|
||||
|
||||
// Eagerly write the number of events which will equal subscriptions unless
|
||||
// there's a fault in parsing (not processing).
|
||||
if !mod.Memory().WriteUint32Le(resultNevents, nsubscriptions) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
|
||||
// Loop through all subscriptions and write their output.
|
||||
|
||||
// Extract FS context, used in the body of the for loop for FS access.
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
// Slice of events that are processed out of the loop (blocking stdin subscribers).
|
||||
var blockingStdinSubs []*event
|
||||
// The timeout is initialized at max Duration, the loop will find the minimum.
|
||||
var timeout time.Duration = 1<<63 - 1
|
||||
// Count of all the subscriptions that have been already written back to outBuf.
|
||||
// nevents*32 returns at all times the offset where the next event should be written:
|
||||
// this way we ensure that there are no gaps between records.
|
||||
nevents := uint32(0)
|
||||
|
||||
// Layout is subscription_u: Union
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#subscription_u
|
||||
for i := uint32(0); i < nsubscriptions; i++ {
|
||||
inOffset := i * 48
|
||||
outOffset := nevents * 32
|
||||
|
||||
eventType := inBuf[inOffset+8] // +8 past userdata
|
||||
// +8 past userdata +8 contents_offset
|
||||
argBuf := inBuf[inOffset+8+8:]
|
||||
userData := inBuf[inOffset : inOffset+8]
|
||||
|
||||
evt := &event{
|
||||
eventType: eventType,
|
||||
userData: userData,
|
||||
errno: wasip1.ErrnoSuccess,
|
||||
}
|
||||
|
||||
switch eventType {
|
||||
case wasip1.EventTypeClock: // handle later
|
||||
newTimeout, err := processClockEvent(argBuf)
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
// Min timeout.
|
||||
if newTimeout < timeout {
|
||||
timeout = newTimeout
|
||||
}
|
||||
// Ack the clock event to the outBuf.
|
||||
writeEvent(outBuf[outOffset:], evt)
|
||||
nevents++
|
||||
case wasip1.EventTypeFdRead:
|
||||
fd := int32(le.Uint32(argBuf))
|
||||
if fd < 0 {
|
||||
return sys.EBADF
|
||||
}
|
||||
if file, ok := fsc.LookupFile(fd); !ok {
|
||||
evt.errno = wasip1.ErrnoBadf
|
||||
writeEvent(outBuf[outOffset:], evt)
|
||||
nevents++
|
||||
} else if fd != internalsys.FdStdin && file.File.IsNonblock() {
|
||||
writeEvent(outBuf[outOffset:], evt)
|
||||
nevents++
|
||||
} else {
|
||||
// if the fd is Stdin, and it is in blocking mode,
|
||||
// do not ack yet, append to a slice for delayed evaluation.
|
||||
blockingStdinSubs = append(blockingStdinSubs, evt)
|
||||
}
|
||||
case wasip1.EventTypeFdWrite:
|
||||
fd := int32(le.Uint32(argBuf))
|
||||
if fd < 0 {
|
||||
return sys.EBADF
|
||||
}
|
||||
if _, ok := fsc.LookupFile(fd); ok {
|
||||
evt.errno = wasip1.ErrnoNotsup
|
||||
} else {
|
||||
evt.errno = wasip1.ErrnoBadf
|
||||
}
|
||||
nevents++
|
||||
writeEvent(outBuf[outOffset:], evt)
|
||||
default:
|
||||
return sys.EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
if nevents == nsubscriptions {
|
||||
// We already wrote back all the results. We already wrote this number
|
||||
// earlier to offset `resultNevents`.
|
||||
// We only need to observe the timeout (nonzero if there are clock subscriptions)
|
||||
// and return.
|
||||
if timeout > 0 {
|
||||
sysCtx.Nanosleep(int64(timeout))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// If there are blocking stdin subscribers, check for data with given timeout.
|
||||
stdin, ok := fsc.LookupFile(internalsys.FdStdin)
|
||||
if !ok {
|
||||
return sys.EBADF
|
||||
}
|
||||
// Wait for the timeout to expire, or for some data to become available on Stdin.
|
||||
|
||||
if stdinReady, errno := stdin.File.Poll(fsapi.POLLIN, int32(timeout.Milliseconds())); errno != 0 {
|
||||
return errno
|
||||
} else if stdinReady {
|
||||
// stdin has data ready to for reading, write back all the events
|
||||
for i := range blockingStdinSubs {
|
||||
evt := blockingStdinSubs[i]
|
||||
evt.errno = 0
|
||||
writeEvent(outBuf[nevents*32:], evt)
|
||||
nevents++
|
||||
}
|
||||
}
|
||||
|
||||
if nevents != nsubscriptions {
|
||||
if !mod.Memory().WriteUint32Le(resultNevents, nevents) {
|
||||
return sys.EFAULT
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// processClockEvent supports only relative name events, as that's what's used
|
||||
// to implement sleep in various compilers including Rust, Zig and TinyGo.
|
||||
func processClockEvent(inBuf []byte) (time.Duration, sys.Errno) {
|
||||
_ /* ID */ = le.Uint32(inBuf[0:8]) // See below
|
||||
timeout := le.Uint64(inBuf[8:16]) // nanos if relative
|
||||
_ /* precision */ = le.Uint64(inBuf[16:24]) // Unused
|
||||
flags := le.Uint16(inBuf[24:32])
|
||||
|
||||
var err sys.Errno
|
||||
// subclockflags has only one flag defined: subscription_clock_abstime
|
||||
switch flags {
|
||||
case 0: // relative time
|
||||
case 1: // subscription_clock_abstime
|
||||
err = sys.ENOTSUP
|
||||
default: // subclockflags has only one flag defined.
|
||||
err = sys.EINVAL
|
||||
}
|
||||
|
||||
if err != 0 {
|
||||
return 0, err
|
||||
} else {
|
||||
// https://linux.die.net/man/3/clock_settime says relative timers are
|
||||
// unaffected. Since this function only supports relative timeout, we can
|
||||
// skip name ID validation and use a single sleep function.
|
||||
|
||||
return time.Duration(timeout), 0
|
||||
}
|
||||
}
|
||||
|
||||
// writeEvent writes the event corresponding to the processed subscription.
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-event-struct
|
||||
func writeEvent(outBuf []byte, evt *event) {
|
||||
copy(outBuf, evt.userData) // userdata
|
||||
outBuf[8] = byte(evt.errno) // uint16, but safe as < 255
|
||||
outBuf[9] = 0
|
||||
le.PutUint32(outBuf[10:], uint32(evt.eventType))
|
||||
// TODO: When FD events are supported, write outOffset+16
|
||||
}
|
44
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go
generated
vendored
Normal file
44
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/proc.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
"github.com/tetratelabs/wazero/sys"
|
||||
)
|
||||
|
||||
// procExit is the WASI function named ProcExitName that terminates the
|
||||
// execution of the module with an exit code. The only successful exit code is
|
||||
// zero.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - exitCode: exit code.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#proc_exit
|
||||
var procExit = &wasm.HostFunc{
|
||||
ExportName: wasip1.ProcExitName,
|
||||
Name: wasip1.ProcExitName,
|
||||
ParamTypes: []api.ValueType{i32},
|
||||
ParamNames: []string{"rval"},
|
||||
Code: wasm.Code{GoFunc: api.GoModuleFunc(procExitFn)},
|
||||
}
|
||||
|
||||
func procExitFn(ctx context.Context, mod api.Module, params []uint64) {
|
||||
exitCode := uint32(params[0])
|
||||
|
||||
// Ensure other callers see the exit code.
|
||||
_ = mod.CloseWithExitCode(ctx, exitCode)
|
||||
|
||||
// Prevent any code from executing after this function. For example, LLVM
|
||||
// inserts unreachable instructions after calls to exit.
|
||||
// See: https://github.com/emscripten-core/emscripten/issues/12322
|
||||
panic(sys.NewExitError(exitCode))
|
||||
}
|
||||
|
||||
// procRaise is stubbed and will never be supported, as it was removed.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/pull/136
|
||||
var procRaise = stubFunction(wasip1.ProcRaiseName, []api.ValueType{i32}, "sig")
|
55
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go
generated
vendored
Normal file
55
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/random.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// randomGet is the WASI function named RandomGetName which writes random
|
||||
// data to a buffer.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
// - buf: api.Memory offset to write random values
|
||||
// - bufLen: size of random data in bytes
|
||||
//
|
||||
// Result (Errno)
|
||||
//
|
||||
// The return value is ErrnoSuccess except the following error conditions:
|
||||
// - sys.EFAULT: `buf` or `bufLen` point to an offset out of memory
|
||||
// - sys.EIO: a file system error
|
||||
//
|
||||
// For example, if underlying random source was seeded like
|
||||
// `rand.NewSource(42)`, we expect api.Memory to contain:
|
||||
//
|
||||
// bufLen (5)
|
||||
// +--------------------------+
|
||||
// | |
|
||||
// []byte{?, 0x53, 0x8c, 0x7f, 0x96, 0xb1, ?}
|
||||
// buf --^
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-random_getbuf-pointeru8-bufLen-size---errno
|
||||
var randomGet = newHostFunc(wasip1.RandomGetName, randomGetFn, []api.ValueType{i32, i32}, "buf", "buf_len")
|
||||
|
||||
func randomGetFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
randSource := sysCtx.RandSource()
|
||||
buf, bufLen := uint32(params[0]), uint32(params[1])
|
||||
|
||||
randomBytes, ok := mod.Memory().Read(buf, bufLen)
|
||||
if !ok { // out-of-range
|
||||
return sys.EFAULT
|
||||
}
|
||||
|
||||
// We can ignore the returned n as it only != byteCount on error
|
||||
if _, err := io.ReadAtLeast(randSource, randomBytes, int(bufLen)); err != nil {
|
||||
return sys.EIO
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
22
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sched.go
generated
vendored
Normal file
22
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sched.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// schedYield is the WASI function named SchedYieldName which temporarily
|
||||
// yields execution of the calling thread.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sched_yield---errno
|
||||
var schedYield = newHostFunc(wasip1.SchedYieldName, schedYieldFn, nil)
|
||||
|
||||
func schedYieldFn(_ context.Context, mod api.Module, _ []uint64) sys.Errno {
|
||||
sysCtx := mod.(*wasm.ModuleInstance).Sys
|
||||
sysCtx.Osyield()
|
||||
return 0
|
||||
}
|
188
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go
generated
vendored
Normal file
188
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/sock.go
generated
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
socketapi "github.com/tetratelabs/wazero/internal/sock"
|
||||
"github.com/tetratelabs/wazero/internal/sysfs"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// sockAccept is the WASI function named SockAcceptName which accepts a new
|
||||
// incoming connection.
|
||||
//
|
||||
// See: https://github.com/WebAssembly/WASI/blob/0ba0c5e2e37625ca5a6d3e4255a998dfaa3efc52/phases/snapshot/docs.md#sock_accept
|
||||
// and https://github.com/WebAssembly/WASI/pull/458
|
||||
var sockAccept = newHostFunc(
|
||||
wasip1.SockAcceptName,
|
||||
sockAcceptFn,
|
||||
[]wasm.ValueType{i32, i32, i32},
|
||||
"fd", "flags", "result.fd",
|
||||
)
|
||||
|
||||
func sockAcceptFn(_ context.Context, mod api.Module, params []uint64) (errno sys.Errno) {
|
||||
mem := mod.Memory()
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
|
||||
fd := int32(params[0])
|
||||
flags := uint32(params[1])
|
||||
resultFd := uint32(params[2])
|
||||
nonblock := flags&uint32(wasip1.FD_NONBLOCK) != 0
|
||||
|
||||
var connFD int32
|
||||
if connFD, errno = fsc.SockAccept(fd, nonblock); errno == 0 {
|
||||
mem.WriteUint32Le(resultFd, uint32(connFD))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// sockRecv is the WASI function named SockRecvName which receives a
|
||||
// message from a socket.
|
||||
//
|
||||
// See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_recvfd-fd-ri_data-iovec_array-ri_flags-riflags---errno-size-roflags
|
||||
var sockRecv = newHostFunc(
|
||||
wasip1.SockRecvName,
|
||||
sockRecvFn,
|
||||
[]wasm.ValueType{i32, i32, i32, i32, i32, i32},
|
||||
"fd", "ri_data", "ri_data_len", "ri_flags", "result.ro_datalen", "result.ro_flags",
|
||||
)
|
||||
|
||||
func sockRecvFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
mem := mod.Memory()
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
|
||||
fd := int32(params[0])
|
||||
riData := uint32(params[1])
|
||||
riDataCount := uint32(params[2])
|
||||
riFlags := uint8(params[3])
|
||||
resultRoDatalen := uint32(params[4])
|
||||
resultRoFlags := uint32(params[5])
|
||||
|
||||
var conn socketapi.TCPConn
|
||||
if e, ok := fsc.LookupFile(fd); !ok {
|
||||
return sys.EBADF // Not open
|
||||
} else if conn, ok = e.File.(socketapi.TCPConn); !ok {
|
||||
return sys.EBADF // Not a conn
|
||||
}
|
||||
|
||||
if riFlags & ^(wasip1.RI_RECV_PEEK|wasip1.RI_RECV_WAITALL) != 0 {
|
||||
return sys.ENOTSUP
|
||||
}
|
||||
|
||||
if riFlags&wasip1.RI_RECV_PEEK != 0 {
|
||||
// Each record in riData is of the form:
|
||||
// type iovec struct { buf *uint8; bufLen uint32 }
|
||||
// This means that the first `uint32` is a `buf *uint8`.
|
||||
firstIovecBufAddr, ok := mem.ReadUint32Le(riData)
|
||||
if !ok {
|
||||
return sys.EINVAL
|
||||
}
|
||||
// Read bufLen
|
||||
firstIovecBufLen, ok := mem.ReadUint32Le(riData + 4)
|
||||
if !ok {
|
||||
return sys.EINVAL
|
||||
}
|
||||
firstIovecBuf, ok := mem.Read(firstIovecBufAddr, firstIovecBufLen)
|
||||
if !ok {
|
||||
return sys.EINVAL
|
||||
}
|
||||
n, err := conn.Recvfrom(firstIovecBuf, sysfs.MSG_PEEK)
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
mem.WriteUint32Le(resultRoDatalen, uint32(n))
|
||||
mem.WriteUint16Le(resultRoFlags, 0)
|
||||
return 0
|
||||
}
|
||||
|
||||
// If riFlags&wasip1.RECV_WAITALL != 0 then we should
|
||||
// do a blocking operation until all data has been retrieved;
|
||||
// otherwise we are able to return earlier.
|
||||
// For simplicity, we currently wait all regardless the flag.
|
||||
bufSize, errno := readv(mem, riData, riDataCount, conn.Read)
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
mem.WriteUint32Le(resultRoDatalen, bufSize)
|
||||
mem.WriteUint16Le(resultRoFlags, 0)
|
||||
return 0
|
||||
}
|
||||
|
||||
// sockSend is the WASI function named SockSendName which sends a message
|
||||
// on a socket.
|
||||
//
|
||||
// See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_sendfd-fd-si_data-ciovec_array-si_flags-siflags---errno-size
|
||||
var sockSend = newHostFunc(
|
||||
wasip1.SockSendName,
|
||||
sockSendFn,
|
||||
[]wasm.ValueType{i32, i32, i32, i32, i32},
|
||||
"fd", "si_data", "si_data_len", "si_flags", "result.so_datalen",
|
||||
)
|
||||
|
||||
func sockSendFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
mem := mod.Memory()
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
|
||||
fd := int32(params[0])
|
||||
siData := uint32(params[1])
|
||||
siDataCount := uint32(params[2])
|
||||
siFlags := uint32(params[3])
|
||||
resultSoDatalen := uint32(params[4])
|
||||
|
||||
if siFlags != 0 {
|
||||
return sys.ENOTSUP
|
||||
}
|
||||
|
||||
var conn socketapi.TCPConn
|
||||
if e, ok := fsc.LookupFile(fd); !ok {
|
||||
return sys.EBADF // Not open
|
||||
} else if conn, ok = e.File.(socketapi.TCPConn); !ok {
|
||||
return sys.EBADF // Not a conn
|
||||
}
|
||||
|
||||
bufSize, errno := writev(mem, siData, siDataCount, conn.Write)
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
mem.WriteUint32Le(resultSoDatalen, bufSize)
|
||||
return 0
|
||||
}
|
||||
|
||||
// sockShutdown is the WASI function named SockShutdownName which shuts
|
||||
// down socket send and receive channels.
|
||||
//
|
||||
// See: https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sock_shutdownfd-fd-how-sdflags---errno
|
||||
var sockShutdown = newHostFunc(wasip1.SockShutdownName, sockShutdownFn, []wasm.ValueType{i32, i32}, "fd", "how")
|
||||
|
||||
func sockShutdownFn(_ context.Context, mod api.Module, params []uint64) sys.Errno {
|
||||
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
|
||||
|
||||
fd := int32(params[0])
|
||||
how := uint8(params[1])
|
||||
|
||||
var conn socketapi.TCPConn
|
||||
if e, ok := fsc.LookupFile(fd); !ok {
|
||||
return sys.EBADF // Not open
|
||||
} else if conn, ok = e.File.(socketapi.TCPConn); !ok {
|
||||
return sys.EBADF // Not a conn
|
||||
}
|
||||
|
||||
sysHow := 0
|
||||
|
||||
switch how {
|
||||
case wasip1.SD_RD | wasip1.SD_WR:
|
||||
sysHow = socketapi.SHUT_RD | socketapi.SHUT_WR
|
||||
case wasip1.SD_RD:
|
||||
sysHow = socketapi.SHUT_RD
|
||||
case wasip1.SD_WR:
|
||||
sysHow = socketapi.SHUT_WR
|
||||
default:
|
||||
return sys.EINVAL
|
||||
}
|
||||
|
||||
// TODO: Map this instead of relying on syscall symbols.
|
||||
return conn.Shutdown(sysHow)
|
||||
}
|
314
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go
generated
vendored
Normal file
314
vendor/github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1/wasi.go
generated
vendored
Normal file
@ -0,0 +1,314 @@
|
||||
// Package wasi_snapshot_preview1 contains Go-defined functions to access
|
||||
// system calls, such as opening a file, similar to Go's x/sys package. These
|
||||
// are accessible from WebAssembly-defined functions via importing ModuleName.
|
||||
// All WASI functions return a single Errno result: ErrnoSuccess on success.
|
||||
//
|
||||
// e.g. Call Instantiate before instantiating any wasm binary that imports
|
||||
// "wasi_snapshot_preview1", Otherwise, it will error due to missing imports.
|
||||
//
|
||||
// ctx := context.Background()
|
||||
// r := wazero.NewRuntime(ctx)
|
||||
// defer r.Close(ctx) // This closes everything this Runtime created.
|
||||
//
|
||||
// wasi_snapshot_preview1.MustInstantiate(ctx, r)
|
||||
// mod, _ := r.Instantiate(ctx, wasm)
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI
|
||||
package wasi_snapshot_preview1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
"github.com/tetratelabs/wazero/internal/wasip1"
|
||||
"github.com/tetratelabs/wazero/internal/wasm"
|
||||
)
|
||||
|
||||
// ModuleName is the module name WASI functions are exported into.
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md
|
||||
const ModuleName = wasip1.InternalModuleName
|
||||
|
||||
const i32, i64 = wasm.ValueTypeI32, wasm.ValueTypeI64
|
||||
|
||||
var le = binary.LittleEndian
|
||||
|
||||
// MustInstantiate calls Instantiate or panics on error.
|
||||
//
|
||||
// This is a simpler function for those who know the module ModuleName is not
|
||||
// already instantiated, and don't need to unload it.
|
||||
func MustInstantiate(ctx context.Context, r wazero.Runtime) {
|
||||
if _, err := Instantiate(ctx, r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Instantiate instantiates the ModuleName module into the runtime.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - Failure cases are documented on wazero.Runtime InstantiateModule.
|
||||
// - Closing the wazero.Runtime has the same effect as closing the result.
|
||||
func Instantiate(ctx context.Context, r wazero.Runtime) (api.Closer, error) {
|
||||
return NewBuilder(r).Instantiate(ctx)
|
||||
}
|
||||
|
||||
// Builder configures the ModuleName module for later use via Compile or Instantiate.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is an interface for decoupling, not third-party implementations.
|
||||
// All implementations are in wazero.
|
||||
type Builder interface {
|
||||
// Compile compiles the ModuleName module. Call this before Instantiate.
|
||||
//
|
||||
// Note: This has the same effect as the same function on wazero.HostModuleBuilder.
|
||||
Compile(context.Context) (wazero.CompiledModule, error)
|
||||
|
||||
// Instantiate instantiates the ModuleName module and returns a function to close it.
|
||||
//
|
||||
// Note: This has the same effect as the same function on wazero.HostModuleBuilder.
|
||||
Instantiate(context.Context) (api.Closer, error)
|
||||
}
|
||||
|
||||
// NewBuilder returns a new Builder.
|
||||
func NewBuilder(r wazero.Runtime) Builder {
|
||||
return &builder{r}
|
||||
}
|
||||
|
||||
type builder struct{ r wazero.Runtime }
|
||||
|
||||
// hostModuleBuilder returns a new wazero.HostModuleBuilder for ModuleName
|
||||
func (b *builder) hostModuleBuilder() wazero.HostModuleBuilder {
|
||||
ret := b.r.NewHostModuleBuilder(ModuleName)
|
||||
exportFunctions(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Compile implements Builder.Compile
|
||||
func (b *builder) Compile(ctx context.Context) (wazero.CompiledModule, error) {
|
||||
return b.hostModuleBuilder().Compile(ctx)
|
||||
}
|
||||
|
||||
// Instantiate implements Builder.Instantiate
|
||||
func (b *builder) Instantiate(ctx context.Context) (api.Closer, error) {
|
||||
return b.hostModuleBuilder().Instantiate(ctx)
|
||||
}
|
||||
|
||||
// FunctionExporter exports functions into a wazero.HostModuleBuilder.
|
||||
//
|
||||
// # Notes
|
||||
//
|
||||
// - This is an interface for decoupling, not third-party implementations.
|
||||
// All implementations are in wazero.
|
||||
type FunctionExporter interface {
|
||||
ExportFunctions(wazero.HostModuleBuilder)
|
||||
}
|
||||
|
||||
// NewFunctionExporter returns a new FunctionExporter. This is used for the
|
||||
// following two use cases:
|
||||
// - Overriding a builtin function with an alternate implementation.
|
||||
// - Exporting functions to the module "wasi_unstable" for legacy code.
|
||||
//
|
||||
// # Example of overriding default behavior
|
||||
//
|
||||
// // Export the default WASI functions.
|
||||
// wasiBuilder := r.NewHostModuleBuilder(ModuleName)
|
||||
// wasi_snapshot_preview1.NewFunctionExporter().ExportFunctions(wasiBuilder)
|
||||
//
|
||||
// // Subsequent calls to NewFunctionBuilder override built-in exports.
|
||||
// wasiBuilder.NewFunctionBuilder().
|
||||
// WithFunc(func(ctx context.Context, mod api.Module, exitCode uint32) {
|
||||
// // your custom logic
|
||||
// }).Export("proc_exit")
|
||||
//
|
||||
// # Example of using the old module name for WASI
|
||||
//
|
||||
// // Instantiate the current WASI functions under the wasi_unstable
|
||||
// // instead of wasi_snapshot_preview1.
|
||||
// wasiBuilder := r.NewHostModuleBuilder("wasi_unstable")
|
||||
// wasi_snapshot_preview1.NewFunctionExporter().ExportFunctions(wasiBuilder)
|
||||
// _, err := wasiBuilder.Instantiate(testCtx, r)
|
||||
func NewFunctionExporter() FunctionExporter {
|
||||
return &functionExporter{}
|
||||
}
|
||||
|
||||
type functionExporter struct{}
|
||||
|
||||
// ExportFunctions implements FunctionExporter.ExportFunctions
|
||||
func (functionExporter) ExportFunctions(builder wazero.HostModuleBuilder) {
|
||||
exportFunctions(builder)
|
||||
}
|
||||
|
||||
// ## Translation notes
|
||||
// ### String
|
||||
// WebAssembly 1.0 has no string type, so any string input parameter expands to two uint32 parameters: offset
|
||||
// and length.
|
||||
//
|
||||
// ### iovec_array
|
||||
// `iovec_array` is encoded as two uin32le values (i32): offset and count.
|
||||
//
|
||||
// ### Result
|
||||
// Each result besides Errno is always an uint32 parameter. WebAssembly 1.0 can have up to one result,
|
||||
// which is already used by Errno. This forces other results to be parameters. A result parameter is a memory
|
||||
// offset to write the result to. As memory offsets are uint32, each parameter representing a result is uint32.
|
||||
//
|
||||
// ### Errno
|
||||
// The WASI specification is sometimes ambiguous resulting in some runtimes interpreting the same function ways.
|
||||
// Errno mappings are not defined in WASI, yet, so these mappings are best efforts by maintainers. When in doubt
|
||||
// about portability, first look at /RATIONALE.md and if needed an issue on
|
||||
// https://github.com/WebAssembly/WASI/issues
|
||||
//
|
||||
// ## Memory
|
||||
// In WebAssembly 1.0 (20191205), there may be up to one Memory per store, which means api.Memory is always the
|
||||
// wasm.Store Memories index zero: `store.Memories[0].Buffer`
|
||||
//
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md
|
||||
// See https://github.com/WebAssembly/WASI/issues/215
|
||||
// See https://wwa.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-instances%E2%91%A0.
|
||||
|
||||
// exportFunctions adds all go functions that implement wasi.
|
||||
// These should be exported in the module named ModuleName.
|
||||
func exportFunctions(builder wazero.HostModuleBuilder) {
|
||||
exporter := builder.(wasm.HostFuncExporter)
|
||||
|
||||
// Note: these are ordered per spec for consistency even if the resulting
|
||||
// map can't guarantee that.
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#functions
|
||||
exporter.ExportHostFunc(argsGet)
|
||||
exporter.ExportHostFunc(argsSizesGet)
|
||||
exporter.ExportHostFunc(environGet)
|
||||
exporter.ExportHostFunc(environSizesGet)
|
||||
exporter.ExportHostFunc(clockResGet)
|
||||
exporter.ExportHostFunc(clockTimeGet)
|
||||
exporter.ExportHostFunc(fdAdvise)
|
||||
exporter.ExportHostFunc(fdAllocate)
|
||||
exporter.ExportHostFunc(fdClose)
|
||||
exporter.ExportHostFunc(fdDatasync)
|
||||
exporter.ExportHostFunc(fdFdstatGet)
|
||||
exporter.ExportHostFunc(fdFdstatSetFlags)
|
||||
exporter.ExportHostFunc(fdFdstatSetRights)
|
||||
exporter.ExportHostFunc(fdFilestatGet)
|
||||
exporter.ExportHostFunc(fdFilestatSetSize)
|
||||
exporter.ExportHostFunc(fdFilestatSetTimes)
|
||||
exporter.ExportHostFunc(fdPread)
|
||||
exporter.ExportHostFunc(fdPrestatGet)
|
||||
exporter.ExportHostFunc(fdPrestatDirName)
|
||||
exporter.ExportHostFunc(fdPwrite)
|
||||
exporter.ExportHostFunc(fdRead)
|
||||
exporter.ExportHostFunc(fdReaddir)
|
||||
exporter.ExportHostFunc(fdRenumber)
|
||||
exporter.ExportHostFunc(fdSeek)
|
||||
exporter.ExportHostFunc(fdSync)
|
||||
exporter.ExportHostFunc(fdTell)
|
||||
exporter.ExportHostFunc(fdWrite)
|
||||
exporter.ExportHostFunc(pathCreateDirectory)
|
||||
exporter.ExportHostFunc(pathFilestatGet)
|
||||
exporter.ExportHostFunc(pathFilestatSetTimes)
|
||||
exporter.ExportHostFunc(pathLink)
|
||||
exporter.ExportHostFunc(pathOpen)
|
||||
exporter.ExportHostFunc(pathReadlink)
|
||||
exporter.ExportHostFunc(pathRemoveDirectory)
|
||||
exporter.ExportHostFunc(pathRename)
|
||||
exporter.ExportHostFunc(pathSymlink)
|
||||
exporter.ExportHostFunc(pathUnlinkFile)
|
||||
exporter.ExportHostFunc(pollOneoff)
|
||||
exporter.ExportHostFunc(procExit)
|
||||
exporter.ExportHostFunc(procRaise)
|
||||
exporter.ExportHostFunc(schedYield)
|
||||
exporter.ExportHostFunc(randomGet)
|
||||
exporter.ExportHostFunc(sockAccept)
|
||||
exporter.ExportHostFunc(sockRecv)
|
||||
exporter.ExportHostFunc(sockSend)
|
||||
exporter.ExportHostFunc(sockShutdown)
|
||||
}
|
||||
|
||||
// writeOffsetsAndNullTerminatedValues is used to write NUL-terminated values
|
||||
// for args or environ, given a pre-defined bytesLen (which includes NUL
|
||||
// terminators).
|
||||
func writeOffsetsAndNullTerminatedValues(mem api.Memory, values [][]byte, offsets, bytes, bytesLen uint32) sys.Errno {
|
||||
// The caller may not place bytes directly after offsets, so we have to
|
||||
// read them independently.
|
||||
valuesLen := len(values)
|
||||
offsetsLen := uint32(valuesLen * 4) // uint32Le
|
||||
offsetsBuf, ok := mem.Read(offsets, offsetsLen)
|
||||
if !ok {
|
||||
return sys.EFAULT
|
||||
}
|
||||
bytesBuf, ok := mem.Read(bytes, bytesLen)
|
||||
if !ok {
|
||||
return sys.EFAULT
|
||||
}
|
||||
|
||||
// Loop through the values, first writing the location of its data to
|
||||
// offsetsBuf[oI], then its NUL-terminated data at bytesBuf[bI]
|
||||
var oI, bI uint32
|
||||
for _, value := range values {
|
||||
// Go can't guarantee inlining as there's not //go:inline directive.
|
||||
// This inlines uint32 little-endian encoding instead.
|
||||
bytesOffset := bytes + bI
|
||||
offsetsBuf[oI] = byte(bytesOffset)
|
||||
offsetsBuf[oI+1] = byte(bytesOffset >> 8)
|
||||
offsetsBuf[oI+2] = byte(bytesOffset >> 16)
|
||||
offsetsBuf[oI+3] = byte(bytesOffset >> 24)
|
||||
oI += 4 // size of uint32 we just wrote
|
||||
|
||||
// Write the next value to memory with a NUL terminator
|
||||
copy(bytesBuf[bI:], value)
|
||||
bI += uint32(len(value))
|
||||
bytesBuf[bI] = 0 // NUL terminator
|
||||
bI++
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func newHostFunc(
|
||||
name string,
|
||||
goFunc wasiFunc,
|
||||
paramTypes []api.ValueType,
|
||||
paramNames ...string,
|
||||
) *wasm.HostFunc {
|
||||
return &wasm.HostFunc{
|
||||
ExportName: name,
|
||||
Name: name,
|
||||
ParamTypes: paramTypes,
|
||||
ParamNames: paramNames,
|
||||
ResultTypes: []api.ValueType{i32},
|
||||
ResultNames: []string{"errno"},
|
||||
Code: wasm.Code{GoFunc: goFunc},
|
||||
}
|
||||
}
|
||||
|
||||
// wasiFunc special cases that all WASI functions return a single Errno
|
||||
// result. The returned value will be written back to the stack at index zero.
|
||||
type wasiFunc func(ctx context.Context, mod api.Module, params []uint64) sys.Errno
|
||||
|
||||
// Call implements the same method as documented on api.GoModuleFunction.
|
||||
func (f wasiFunc) Call(ctx context.Context, mod api.Module, stack []uint64) {
|
||||
// Write the result back onto the stack
|
||||
errno := f(ctx, mod, stack)
|
||||
if errno != 0 {
|
||||
stack[0] = uint64(wasip1.ToErrno(errno))
|
||||
} else { // special case ass ErrnoSuccess is zero
|
||||
stack[0] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// stubFunction stubs for GrainLang per #271.
|
||||
func stubFunction(name string, paramTypes []wasm.ValueType, paramNames ...string) *wasm.HostFunc {
|
||||
return &wasm.HostFunc{
|
||||
ExportName: name,
|
||||
Name: name,
|
||||
ParamTypes: paramTypes,
|
||||
ParamNames: paramNames,
|
||||
ResultTypes: []api.ValueType{i32},
|
||||
ResultNames: []string{"errno"},
|
||||
Code: wasm.Code{
|
||||
GoFunc: api.GoModuleFunc(func(_ context.Context, _ api.Module, stack []uint64) { stack[0] = uint64(wasip1.ErrnoNosys) }),
|
||||
},
|
||||
}
|
||||
}
|
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/args.go
generated
vendored
Normal file
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/args.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package wasip1
|
||||
|
||||
const (
|
||||
ArgsGetName = "args_get"
|
||||
ArgsSizesGetName = "args_sizes_get"
|
||||
)
|
16
vendor/github.com/tetratelabs/wazero/internal/wasip1/clock.go
generated
vendored
Normal file
16
vendor/github.com/tetratelabs/wazero/internal/wasip1/clock.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package wasip1
|
||||
|
||||
const (
|
||||
ClockResGetName = "clock_res_get"
|
||||
ClockTimeGetName = "clock_time_get"
|
||||
)
|
||||
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-clockid-enumu32
|
||||
const (
|
||||
// ClockIDRealtime is the name ID named "realtime" like sys.Walltime
|
||||
ClockIDRealtime = iota
|
||||
// ClockIDMonotonic is the name ID named "monotonic" like sys.Nanotime
|
||||
ClockIDMonotonic
|
||||
// Note: clockIDProcessCputime and clockIDThreadCputime were removed by
|
||||
// WASI maintainers: https://github.com/WebAssembly/wasi-libc/pull/294
|
||||
)
|
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/environ.go
generated
vendored
Normal file
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/environ.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package wasip1
|
||||
|
||||
const (
|
||||
EnvironGetName = "environ_get"
|
||||
EnvironSizesGetName = "environ_sizes_get"
|
||||
)
|
314
vendor/github.com/tetratelabs/wazero/internal/wasip1/errno.go
generated
vendored
Normal file
314
vendor/github.com/tetratelabs/wazero/internal/wasip1/errno.go
generated
vendored
Normal file
@ -0,0 +1,314 @@
|
||||
package wasip1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tetratelabs/wazero/experimental/sys"
|
||||
)
|
||||
|
||||
// Errno is neither uint16 nor an alias for parity with wasm.ValueType.
|
||||
type Errno = uint32
|
||||
|
||||
// ErrnoName returns the POSIX error code name, except ErrnoSuccess, which is
|
||||
// not an error. e.g. Errno2big -> "E2BIG"
|
||||
func ErrnoName(errno uint32) string {
|
||||
if int(errno) < len(errnoToString) {
|
||||
return errnoToString[errno]
|
||||
}
|
||||
return fmt.Sprintf("errno(%d)", errno)
|
||||
}
|
||||
|
||||
// Note: Below prefers POSIX symbol names over WASI ones, even if the docs are from WASI.
|
||||
// See https://linux.die.net/man/3/errno
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#variants-1
|
||||
const (
|
||||
// ErrnoSuccess No error occurred. System call completed successfully.
|
||||
ErrnoSuccess Errno = iota
|
||||
// Errno2big Argument list too long.
|
||||
Errno2big
|
||||
// ErrnoAcces Permission denied.
|
||||
ErrnoAcces
|
||||
// ErrnoAddrinuse Address in use.
|
||||
ErrnoAddrinuse
|
||||
// ErrnoAddrnotavail Address not available.
|
||||
ErrnoAddrnotavail
|
||||
// ErrnoAfnosupport Address family not supported.
|
||||
ErrnoAfnosupport
|
||||
// ErrnoAgain Resource unavailable, or operation would block.
|
||||
ErrnoAgain
|
||||
// ErrnoAlready Connection already in progress.
|
||||
ErrnoAlready
|
||||
// ErrnoBadf Bad file descriptor.
|
||||
ErrnoBadf
|
||||
// ErrnoBadmsg Bad message.
|
||||
ErrnoBadmsg
|
||||
// ErrnoBusy Device or resource busy.
|
||||
ErrnoBusy
|
||||
// ErrnoCanceled Operation canceled.
|
||||
ErrnoCanceled
|
||||
// ErrnoChild No child processes.
|
||||
ErrnoChild
|
||||
// ErrnoConnaborted Connection aborted.
|
||||
ErrnoConnaborted
|
||||
// ErrnoConnrefused Connection refused.
|
||||
ErrnoConnrefused
|
||||
// ErrnoConnreset Connection reset.
|
||||
ErrnoConnreset
|
||||
// ErrnoDeadlk Resource deadlock would occur.
|
||||
ErrnoDeadlk
|
||||
// ErrnoDestaddrreq Destination address required.
|
||||
ErrnoDestaddrreq
|
||||
// ErrnoDom Mathematics argument out of domain of function.
|
||||
ErrnoDom
|
||||
// ErrnoDquot Reserved.
|
||||
ErrnoDquot
|
||||
// ErrnoExist File exists.
|
||||
ErrnoExist
|
||||
// ErrnoFault Bad address.
|
||||
ErrnoFault
|
||||
// ErrnoFbig File too large.
|
||||
ErrnoFbig
|
||||
// ErrnoHostunreach Host is unreachable.
|
||||
ErrnoHostunreach
|
||||
// ErrnoIdrm Identifier removed.
|
||||
ErrnoIdrm
|
||||
// ErrnoIlseq Illegal byte sequence.
|
||||
ErrnoIlseq
|
||||
// ErrnoInprogress Operation in progress.
|
||||
ErrnoInprogress
|
||||
// ErrnoIntr Interrupted function.
|
||||
ErrnoIntr
|
||||
// ErrnoInval Invalid argument.
|
||||
ErrnoInval
|
||||
// ErrnoIo I/O error.
|
||||
ErrnoIo
|
||||
// ErrnoIsconn Socket is connected.
|
||||
ErrnoIsconn
|
||||
// ErrnoIsdir Is a directory.
|
||||
ErrnoIsdir
|
||||
// ErrnoLoop Too many levels of symbolic links.
|
||||
ErrnoLoop
|
||||
// ErrnoMfile File descriptor value too large.
|
||||
ErrnoMfile
|
||||
// ErrnoMlink Too many links.
|
||||
ErrnoMlink
|
||||
// ErrnoMsgsize Message too large.
|
||||
ErrnoMsgsize
|
||||
// ErrnoMultihop Reserved.
|
||||
ErrnoMultihop
|
||||
// ErrnoNametoolong Filename too long.
|
||||
ErrnoNametoolong
|
||||
// ErrnoNetdown Network is down.
|
||||
ErrnoNetdown
|
||||
// ErrnoNetreset Connection aborted by network.
|
||||
ErrnoNetreset
|
||||
// ErrnoNetunreach Network unreachable.
|
||||
ErrnoNetunreach
|
||||
// ErrnoNfile Too many files open in system.
|
||||
ErrnoNfile
|
||||
// ErrnoNobufs No buffer space available.
|
||||
ErrnoNobufs
|
||||
// ErrnoNodev No such device.
|
||||
ErrnoNodev
|
||||
// ErrnoNoent No such file or directory.
|
||||
ErrnoNoent
|
||||
// ErrnoNoexec Executable file format error.
|
||||
ErrnoNoexec
|
||||
// ErrnoNolck No locks available.
|
||||
ErrnoNolck
|
||||
// ErrnoNolink Reserved.
|
||||
ErrnoNolink
|
||||
// ErrnoNomem Not enough space.
|
||||
ErrnoNomem
|
||||
// ErrnoNomsg No message of the desired type.
|
||||
ErrnoNomsg
|
||||
// ErrnoNoprotoopt No message of the desired type.
|
||||
ErrnoNoprotoopt
|
||||
// ErrnoNospc No space left on device.
|
||||
ErrnoNospc
|
||||
// ErrnoNosys function not supported.
|
||||
ErrnoNosys
|
||||
// ErrnoNotconn The socket is not connected.
|
||||
ErrnoNotconn
|
||||
// ErrnoNotdir Not a directory or a symbolic link to a directory.
|
||||
ErrnoNotdir
|
||||
// ErrnoNotempty Directory not empty.
|
||||
ErrnoNotempty
|
||||
// ErrnoNotrecoverable State not recoverable.
|
||||
ErrnoNotrecoverable
|
||||
// ErrnoNotsock Not a socket.
|
||||
ErrnoNotsock
|
||||
// ErrnoNotsup Not supported, or operation not supported on socket.
|
||||
ErrnoNotsup
|
||||
// ErrnoNotty Inappropriate I/O control operation.
|
||||
ErrnoNotty
|
||||
// ErrnoNxio No such device or address.
|
||||
ErrnoNxio
|
||||
// ErrnoOverflow Value too large to be stored in data type.
|
||||
ErrnoOverflow
|
||||
// ErrnoOwnerdead Previous owner died.
|
||||
ErrnoOwnerdead
|
||||
// ErrnoPerm Operation not permitted.
|
||||
ErrnoPerm
|
||||
// ErrnoPipe Broken pipe.
|
||||
ErrnoPipe
|
||||
// ErrnoProto Protocol error.
|
||||
ErrnoProto
|
||||
// ErrnoProtonosupport Protocol error.
|
||||
ErrnoProtonosupport
|
||||
// ErrnoPrototype Protocol wrong type for socket.
|
||||
ErrnoPrototype
|
||||
// ErrnoRange Result too large.
|
||||
ErrnoRange
|
||||
// ErrnoRofs Read-only file system.
|
||||
ErrnoRofs
|
||||
// ErrnoSpipe Invalid seek.
|
||||
ErrnoSpipe
|
||||
// ErrnoSrch No such process.
|
||||
ErrnoSrch
|
||||
// ErrnoStale Reserved.
|
||||
ErrnoStale
|
||||
// ErrnoTimedout Connection timed out.
|
||||
ErrnoTimedout
|
||||
// ErrnoTxtbsy Text file busy.
|
||||
ErrnoTxtbsy
|
||||
// ErrnoXdev Cross-device link.
|
||||
ErrnoXdev
|
||||
|
||||
// Note: ErrnoNotcapable was removed by WASI maintainers.
|
||||
// See https://github.com/WebAssembly/wasi-libc/pull/294
|
||||
)
|
||||
|
||||
var errnoToString = [...]string{
|
||||
"ESUCCESS",
|
||||
"E2BIG",
|
||||
"EACCES",
|
||||
"EADDRINUSE",
|
||||
"EADDRNOTAVAIL",
|
||||
"EAFNOSUPPORT",
|
||||
"EAGAIN",
|
||||
"EALREADY",
|
||||
"EBADF",
|
||||
"EBADMSG",
|
||||
"EBUSY",
|
||||
"ECANCELED",
|
||||
"ECHILD",
|
||||
"ECONNABORTED",
|
||||
"ECONNREFUSED",
|
||||
"ECONNRESET",
|
||||
"EDEADLK",
|
||||
"EDESTADDRREQ",
|
||||
"EDOM",
|
||||
"EDQUOT",
|
||||
"EEXIST",
|
||||
"EFAULT",
|
||||
"EFBIG",
|
||||
"EHOSTUNREACH",
|
||||
"EIDRM",
|
||||
"EILSEQ",
|
||||
"EINPROGRESS",
|
||||
"EINTR",
|
||||
"EINVAL",
|
||||
"EIO",
|
||||
"EISCONN",
|
||||
"EISDIR",
|
||||
"ELOOP",
|
||||
"EMFILE",
|
||||
"EMLINK",
|
||||
"EMSGSIZE",
|
||||
"EMULTIHOP",
|
||||
"ENAMETOOLONG",
|
||||
"ENETDOWN",
|
||||
"ENETRESET",
|
||||
"ENETUNREACH",
|
||||
"ENFILE",
|
||||
"ENOBUFS",
|
||||
"ENODEV",
|
||||
"ENOENT",
|
||||
"ENOEXEC",
|
||||
"ENOLCK",
|
||||
"ENOLINK",
|
||||
"ENOMEM",
|
||||
"ENOMSG",
|
||||
"ENOPROTOOPT",
|
||||
"ENOSPC",
|
||||
"ENOSYS",
|
||||
"ENOTCONN",
|
||||
"ENOTDIR",
|
||||
"ENOTEMPTY",
|
||||
"ENOTRECOVERABLE",
|
||||
"ENOTSOCK",
|
||||
"ENOTSUP",
|
||||
"ENOTTY",
|
||||
"ENXIO",
|
||||
"EOVERFLOW",
|
||||
"EOWNERDEAD",
|
||||
"EPERM",
|
||||
"EPIPE",
|
||||
"EPROTO",
|
||||
"EPROTONOSUPPORT",
|
||||
"EPROTOTYPE",
|
||||
"ERANGE",
|
||||
"EROFS",
|
||||
"ESPIPE",
|
||||
"ESRCH",
|
||||
"ESTALE",
|
||||
"ETIMEDOUT",
|
||||
"ETXTBSY",
|
||||
"EXDEV",
|
||||
"ENOTCAPABLE",
|
||||
}
|
||||
|
||||
// ToErrno coerces the error to a WASI Errno.
|
||||
//
|
||||
// Note: Coercion isn't centralized in sys.FSContext because ABI use different
|
||||
// error codes. For example, wasi-filesystem doesn't map to these
|
||||
// Errno.
|
||||
func ToErrno(errno sys.Errno) Errno {
|
||||
switch errno {
|
||||
case 0:
|
||||
return ErrnoSuccess
|
||||
case sys.EACCES:
|
||||
return ErrnoAcces
|
||||
case sys.EAGAIN:
|
||||
return ErrnoAgain
|
||||
case sys.EBADF:
|
||||
return ErrnoBadf
|
||||
case sys.EEXIST:
|
||||
return ErrnoExist
|
||||
case sys.EFAULT:
|
||||
return ErrnoFault
|
||||
case sys.EINTR:
|
||||
return ErrnoIntr
|
||||
case sys.EINVAL:
|
||||
return ErrnoInval
|
||||
case sys.EIO:
|
||||
return ErrnoIo
|
||||
case sys.EISDIR:
|
||||
return ErrnoIsdir
|
||||
case sys.ELOOP:
|
||||
return ErrnoLoop
|
||||
case sys.ENAMETOOLONG:
|
||||
return ErrnoNametoolong
|
||||
case sys.ENOENT:
|
||||
return ErrnoNoent
|
||||
case sys.ENOSYS:
|
||||
return ErrnoNosys
|
||||
case sys.ENOTDIR:
|
||||
return ErrnoNotdir
|
||||
case sys.ERANGE:
|
||||
return ErrnoRange
|
||||
case sys.ENOTEMPTY:
|
||||
return ErrnoNotempty
|
||||
case sys.ENOTSOCK:
|
||||
return ErrnoNotsock
|
||||
case sys.ENOTSUP:
|
||||
return ErrnoNotsup
|
||||
case sys.EPERM:
|
||||
return ErrnoPerm
|
||||
case sys.EROFS:
|
||||
return ErrnoRofs
|
||||
default:
|
||||
return ErrnoIo
|
||||
}
|
||||
}
|
164
vendor/github.com/tetratelabs/wazero/internal/wasip1/fs.go
generated
vendored
Normal file
164
vendor/github.com/tetratelabs/wazero/internal/wasip1/fs.go
generated
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
package wasip1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
FdAdviseName = "fd_advise"
|
||||
FdAllocateName = "fd_allocate"
|
||||
FdCloseName = "fd_close"
|
||||
FdDatasyncName = "fd_datasync"
|
||||
FdFdstatGetName = "fd_fdstat_get"
|
||||
FdFdstatSetFlagsName = "fd_fdstat_set_flags"
|
||||
FdFdstatSetRightsName = "fd_fdstat_set_rights"
|
||||
FdFilestatGetName = "fd_filestat_get"
|
||||
FdFilestatSetSizeName = "fd_filestat_set_size"
|
||||
FdFilestatSetTimesName = "fd_filestat_set_times"
|
||||
FdPreadName = "fd_pread"
|
||||
FdPrestatGetName = "fd_prestat_get"
|
||||
FdPrestatDirNameName = "fd_prestat_dir_name"
|
||||
FdPwriteName = "fd_pwrite"
|
||||
FdReadName = "fd_read"
|
||||
FdReaddirName = "fd_readdir"
|
||||
FdRenumberName = "fd_renumber"
|
||||
FdSeekName = "fd_seek"
|
||||
FdSyncName = "fd_sync"
|
||||
FdTellName = "fd_tell"
|
||||
FdWriteName = "fd_write"
|
||||
|
||||
PathCreateDirectoryName = "path_create_directory"
|
||||
PathFilestatGetName = "path_filestat_get"
|
||||
PathFilestatSetTimesName = "path_filestat_set_times"
|
||||
PathLinkName = "path_link"
|
||||
PathOpenName = "path_open"
|
||||
PathReadlinkName = "path_readlink"
|
||||
PathRemoveDirectoryName = "path_remove_directory"
|
||||
PathRenameName = "path_rename"
|
||||
PathSymlinkName = "path_symlink"
|
||||
PathUnlinkFileName = "path_unlink_file"
|
||||
)
|
||||
|
||||
// oflags are open flags used by path_open
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-oflags-flagsu16
|
||||
const (
|
||||
// O_CREAT creates a file if it does not exist.
|
||||
O_CREAT uint16 = 1 << iota //nolint
|
||||
// O_DIRECTORY fails if not a directory.
|
||||
O_DIRECTORY
|
||||
// O_EXCL fails if file already exists.
|
||||
O_EXCL //nolint
|
||||
// O_TRUNC truncates the file to size 0.
|
||||
O_TRUNC //nolint
|
||||
)
|
||||
|
||||
func OflagsString(oflags int) string {
|
||||
return flagsString(oflagNames[:], oflags)
|
||||
}
|
||||
|
||||
var oflagNames = [...]string{
|
||||
"CREAT",
|
||||
"DIRECTORY",
|
||||
"EXCL",
|
||||
"TRUNC",
|
||||
}
|
||||
|
||||
// file descriptor flags
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fdflags
|
||||
const (
|
||||
FD_APPEND uint16 = 1 << iota //nolint
|
||||
FD_DSYNC
|
||||
FD_NONBLOCK
|
||||
FD_RSYNC
|
||||
FD_SYNC
|
||||
)
|
||||
|
||||
func FdFlagsString(fdflags int) string {
|
||||
return flagsString(fdflagNames[:], fdflags)
|
||||
}
|
||||
|
||||
var fdflagNames = [...]string{
|
||||
"APPEND",
|
||||
"DSYNC",
|
||||
"NONBLOCK",
|
||||
"RSYNC",
|
||||
"SYNC",
|
||||
}
|
||||
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#lookupflags
|
||||
const (
|
||||
// LOOKUP_SYMLINK_FOLLOW expands a path if it resolves into a symbolic
|
||||
// link.
|
||||
LOOKUP_SYMLINK_FOLLOW uint16 = 1 << iota //nolint
|
||||
)
|
||||
|
||||
var lookupflagNames = [...]string{
|
||||
"SYMLINK_FOLLOW",
|
||||
}
|
||||
|
||||
func LookupflagsString(lookupflags int) string {
|
||||
return flagsString(lookupflagNames[:], lookupflags)
|
||||
}
|
||||
|
||||
// DirentSize is the size of the dirent struct, which should be followed by the
|
||||
// length of a file name.
|
||||
const DirentSize = uint32(24)
|
||||
|
||||
const (
|
||||
FILETYPE_UNKNOWN uint8 = iota
|
||||
FILETYPE_BLOCK_DEVICE
|
||||
FILETYPE_CHARACTER_DEVICE
|
||||
FILETYPE_DIRECTORY
|
||||
FILETYPE_REGULAR_FILE
|
||||
FILETYPE_SOCKET_DGRAM
|
||||
FILETYPE_SOCKET_STREAM
|
||||
FILETYPE_SYMBOLIC_LINK
|
||||
)
|
||||
|
||||
// FiletypeName returns string name of the file type.
|
||||
func FiletypeName(filetype uint8) string {
|
||||
if int(filetype) < len(filetypeToString) {
|
||||
return filetypeToString[filetype]
|
||||
}
|
||||
return fmt.Sprintf("filetype(%d)", filetype)
|
||||
}
|
||||
|
||||
var filetypeToString = [...]string{
|
||||
"UNKNOWN",
|
||||
"BLOCK_DEVICE",
|
||||
"CHARACTER_DEVICE",
|
||||
"DIRECTORY",
|
||||
"REGULAR_FILE",
|
||||
"SOCKET_DGRAM",
|
||||
"SOCKET_STREAM",
|
||||
"SYMBOLIC_LINK",
|
||||
}
|
||||
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#fstflags
|
||||
const (
|
||||
FstflagsAtim uint16 = 1 << iota
|
||||
FstflagsAtimNow
|
||||
FstflagsMtim
|
||||
FstflagsMtimNow
|
||||
)
|
||||
|
||||
var fstflagNames = [...]string{
|
||||
"ATIM",
|
||||
"ATIM_NOW",
|
||||
"MTIM",
|
||||
"MTIM_NOW",
|
||||
}
|
||||
|
||||
func FstflagsString(fdflags int) string {
|
||||
return flagsString(fstflagNames[:], fdflags)
|
||||
}
|
||||
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-advice-enumu8
|
||||
const (
|
||||
FdAdviceNormal byte = iota
|
||||
FdAdviceSequential
|
||||
FdAdviceRandom
|
||||
FdAdviceWillNeed
|
||||
FdAdviceDontNeed
|
||||
FdAdviceNoReuse
|
||||
)
|
15
vendor/github.com/tetratelabs/wazero/internal/wasip1/poll.go
generated
vendored
Normal file
15
vendor/github.com/tetratelabs/wazero/internal/wasip1/poll.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package wasip1
|
||||
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-eventtype-enumu8
|
||||
const (
|
||||
// EventTypeClock is the timeout event named "name".
|
||||
EventTypeClock = iota
|
||||
// EventTypeFdRead is the data available event named "fd_read".
|
||||
EventTypeFdRead
|
||||
// EventTypeFdWrite is the capacity available event named "fd_write".
|
||||
EventTypeFdWrite
|
||||
)
|
||||
|
||||
const (
|
||||
PollOneoffName = "poll_oneoff"
|
||||
)
|
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/proc.go
generated
vendored
Normal file
6
vendor/github.com/tetratelabs/wazero/internal/wasip1/proc.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
package wasip1
|
||||
|
||||
const (
|
||||
ProcExitName = "proc_exit"
|
||||
ProcRaiseName = "proc_raise"
|
||||
)
|
3
vendor/github.com/tetratelabs/wazero/internal/wasip1/random.go
generated
vendored
Normal file
3
vendor/github.com/tetratelabs/wazero/internal/wasip1/random.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package wasip1
|
||||
|
||||
const RandomGetName = "random_get"
|
148
vendor/github.com/tetratelabs/wazero/internal/wasip1/rights.go
generated
vendored
Normal file
148
vendor/github.com/tetratelabs/wazero/internal/wasip1/rights.go
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
package wasip1
|
||||
|
||||
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-rights-flagsu64
|
||||
const (
|
||||
// RIGHT_FD_DATASYNC is the right to invoke fd_datasync. If RIGHT_PATH_OPEN
|
||||
// is set, includes the right to invoke path_open with FD_DSYNC.
|
||||
RIGHT_FD_DATASYNC uint32 = 1 << iota //nolint
|
||||
|
||||
// RIGHT_FD_READ is he right to invoke fd_read and sock_recv. If
|
||||
// RIGHT_FD_SYNC is set, includes the right to invoke fd_pread.
|
||||
RIGHT_FD_READ
|
||||
|
||||
// RIGHT_FD_SEEK is the right to invoke fd_seek. This flag implies
|
||||
// RIGHT_FD_TELL.
|
||||
RIGHT_FD_SEEK
|
||||
|
||||
// RIGHT_FDSTAT_SET_FLAGS is the right to invoke fd_fdstat_set_flags.
|
||||
RIGHT_FDSTAT_SET_FLAGS
|
||||
|
||||
// RIGHT_FD_SYNC The right to invoke fd_sync. If path_open is set, includes
|
||||
// the right to invoke path_open with FD_RSYNC and FD_DSYNC.
|
||||
RIGHT_FD_SYNC
|
||||
|
||||
// RIGHT_FD_TELL is the right to invoke fd_seek in such a way that the file
|
||||
// offset remains unaltered (i.e., whence::cur with offset zero), or to
|
||||
// invoke fd_tell.
|
||||
RIGHT_FD_TELL
|
||||
|
||||
// RIGHT_FD_WRITE is the right to invoke fd_write and sock_send. If
|
||||
// RIGHT_FD_SEEK is set, includes the right to invoke fd_pwrite.
|
||||
RIGHT_FD_WRITE
|
||||
|
||||
// RIGHT_FD_ADVISE is the right to invoke fd_advise.
|
||||
RIGHT_FD_ADVISE
|
||||
|
||||
// RIGHT_FD_ALLOCATE is the right to invoke fd_allocate.
|
||||
RIGHT_FD_ALLOCATE
|
||||
|
||||
// RIGHT_PATH_CREATE_DIRECTORY is the right to invoke
|
||||
// path_create_directory.
|
||||
RIGHT_PATH_CREATE_DIRECTORY
|
||||
|
||||
// RIGHT_PATH_CREATE_FILE when RIGHT_PATH_OPEN is set, the right to invoke
|
||||
// path_open with O_CREAT.
|
||||
RIGHT_PATH_CREATE_FILE
|
||||
|
||||
// RIGHT_PATH_LINK_SOURCE is the right to invoke path_link with the file
|
||||
// descriptor as the source directory.
|
||||
RIGHT_PATH_LINK_SOURCE
|
||||
|
||||
// RIGHT_PATH_LINK_TARGET is the right to invoke path_link with the file
|
||||
// descriptor as the target directory.
|
||||
RIGHT_PATH_LINK_TARGET
|
||||
|
||||
// RIGHT_PATH_OPEN is the right to invoke path_open.
|
||||
RIGHT_PATH_OPEN
|
||||
|
||||
// RIGHT_FD_READDIR is the right to invoke fd_readdir.
|
||||
RIGHT_FD_READDIR
|
||||
|
||||
// RIGHT_PATH_READLINK is the right to invoke path_readlink.
|
||||
RIGHT_PATH_READLINK
|
||||
|
||||
// RIGHT_PATH_RENAME_SOURCE is the right to invoke path_rename with the
|
||||
// file descriptor as the source directory.
|
||||
RIGHT_PATH_RENAME_SOURCE
|
||||
|
||||
// RIGHT_PATH_RENAME_TARGET is the right to invoke path_rename with the
|
||||
// file descriptor as the target directory.
|
||||
RIGHT_PATH_RENAME_TARGET
|
||||
|
||||
// RIGHT_PATH_FILESTAT_GET is the right to invoke path_filestat_get.
|
||||
RIGHT_PATH_FILESTAT_GET
|
||||
|
||||
// RIGHT_PATH_FILESTAT_SET_SIZE is the right to change a file's size (there
|
||||
// is no path_filestat_set_size). If RIGHT_PATH_OPEN is set, includes the
|
||||
// right to invoke path_open with O_TRUNC.
|
||||
RIGHT_PATH_FILESTAT_SET_SIZE
|
||||
|
||||
// RIGHT_PATH_FILESTAT_SET_TIMES is the right to invoke
|
||||
// path_filestat_set_times.
|
||||
RIGHT_PATH_FILESTAT_SET_TIMES
|
||||
|
||||
// RIGHT_FD_FILESTAT_GET is the right to invoke fd_filestat_get.
|
||||
RIGHT_FD_FILESTAT_GET
|
||||
|
||||
// RIGHT_FD_FILESTAT_SET_SIZE is the right to invoke fd_filestat_set_size.
|
||||
RIGHT_FD_FILESTAT_SET_SIZE
|
||||
|
||||
// RIGHT_FD_FILESTAT_SET_TIMES is the right to invoke
|
||||
// fd_filestat_set_times.
|
||||
RIGHT_FD_FILESTAT_SET_TIMES
|
||||
|
||||
// RIGHT_PATH_SYMLINK is the right to invoke path_symlink.
|
||||
RIGHT_PATH_SYMLINK
|
||||
|
||||
// RIGHT_PATH_REMOVE_DIRECTORY is the right to invoke
|
||||
// path_remove_directory.
|
||||
RIGHT_PATH_REMOVE_DIRECTORY
|
||||
|
||||
// RIGHT_PATH_UNLINK_FILE is the right to invoke path_unlink_file.
|
||||
RIGHT_PATH_UNLINK_FILE
|
||||
|
||||
// RIGHT_POLL_FD_READWRITE when RIGHT_FD_READ is set, includes the right to
|
||||
// invoke poll_oneoff to subscribe to eventtype::fd_read. If RIGHT_FD_WRITE
|
||||
// is set, includes the right to invoke poll_oneoff to subscribe to
|
||||
// eventtype::fd_write.
|
||||
RIGHT_POLL_FD_READWRITE
|
||||
|
||||
// RIGHT_SOCK_SHUTDOWN is the right to invoke sock_shutdown.
|
||||
RIGHT_SOCK_SHUTDOWN
|
||||
)
|
||||
|
||||
func RightsString(rights int) string {
|
||||
return flagsString(rightNames[:], rights)
|
||||
}
|
||||
|
||||
var rightNames = [...]string{
|
||||
"FD_DATASYNC",
|
||||
"FD_READ",
|
||||
"FD_SEEK",
|
||||
"FDSTAT_SET_FLAGS",
|
||||
"FD_SYNC",
|
||||
"FD_TELL",
|
||||
"FD_WRITE",
|
||||
"FD_ADVISE",
|
||||
"FD_ALLOCATE",
|
||||
"PATH_CREATE_DIRECTORY",
|
||||
"PATH_CREATE_FILE",
|
||||
"PATH_LINK_SOURCE",
|
||||
"PATH_LINK_TARGET",
|
||||
"PATH_OPEN",
|
||||
"FD_READDIR",
|
||||
"PATH_READLINK",
|
||||
"PATH_RENAME_SOURCE",
|
||||
"PATH_RENAME_TARGET",
|
||||
"PATH_FILESTAT_GET",
|
||||
"PATH_FILESTAT_SET_SIZE",
|
||||
"PATH_FILESTAT_SET_TIMES",
|
||||
"FD_FILESTAT_GET",
|
||||
"FD_FILESTAT_SET_SIZE",
|
||||
"FD_FILESTAT_SET_TIMES",
|
||||
"PATH_SYMLINK",
|
||||
"PATH_REMOVE_DIRECTORY",
|
||||
"PATH_UNLINK_FILE",
|
||||
"POLL_FD_READWRITE",
|
||||
"SOCK_SHUTDOWN",
|
||||
}
|
3
vendor/github.com/tetratelabs/wazero/internal/wasip1/sched.go
generated
vendored
Normal file
3
vendor/github.com/tetratelabs/wazero/internal/wasip1/sched.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package wasip1
|
||||
|
||||
const SchedYieldName = "sched_yield"
|
71
vendor/github.com/tetratelabs/wazero/internal/wasip1/sock.go
generated
vendored
Normal file
71
vendor/github.com/tetratelabs/wazero/internal/wasip1/sock.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
package wasip1
|
||||
|
||||
import "strconv"
|
||||
|
||||
const (
|
||||
SockAcceptName = "sock_accept"
|
||||
SockRecvName = "sock_recv"
|
||||
SockSendName = "sock_send"
|
||||
SockShutdownName = "sock_shutdown"
|
||||
)
|
||||
|
||||
// SD Flags indicate which channels on a socket to shut down.
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-sdflags-flagsu8
|
||||
const (
|
||||
// SD_RD disables further receive operations.
|
||||
SD_RD uint8 = 1 << iota //nolint
|
||||
// SD_WR disables further send operations.
|
||||
SD_WR
|
||||
)
|
||||
|
||||
func SdFlagsString(sdflags int) string {
|
||||
return flagsString(sdflagNames[:], sdflags)
|
||||
}
|
||||
|
||||
var sdflagNames = [...]string{
|
||||
"RD",
|
||||
"WR",
|
||||
}
|
||||
|
||||
// SI Flags are flags provided to sock_send. As there are currently no flags defined, it must be set to zero.
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-siflags-u16
|
||||
|
||||
func SiFlagsString(siflags int) string {
|
||||
if siflags == 0 {
|
||||
return ""
|
||||
}
|
||||
return strconv.Itoa(siflags)
|
||||
}
|
||||
|
||||
// RI Flags are flags provided to sock_recv.
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-riflags-flagsu16
|
||||
const (
|
||||
// RI_RECV_PEEK returns the message without removing it from the socket's receive queue
|
||||
RI_RECV_PEEK uint8 = 1 << iota //nolint
|
||||
// RI_RECV_WAITALL on byte-stream sockets, block until the full amount of data can be returned.
|
||||
RI_RECV_WAITALL
|
||||
)
|
||||
|
||||
func RiFlagsString(riflags int) string {
|
||||
return flagsString(riflagNames[:], riflags)
|
||||
}
|
||||
|
||||
var riflagNames = [...]string{
|
||||
"RECV_PEEK",
|
||||
"RECV_WAITALL",
|
||||
}
|
||||
|
||||
// RO Flags are flags returned by sock_recv.
|
||||
// https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md#-roflags-flagsu16
|
||||
const (
|
||||
// RO_RECV_DATA_TRUNCATED is returned by sock_recv when message data has been truncated.
|
||||
RO_RECV_DATA_TRUNCATED uint8 = 1 << iota //nolint
|
||||
)
|
||||
|
||||
func RoFlagsString(roflags int) string {
|
||||
return flagsString(roflagNames[:], roflags)
|
||||
}
|
||||
|
||||
var roflagNames = [...]string{
|
||||
"RECV_DATA_TRUNCATED",
|
||||
}
|
26
vendor/github.com/tetratelabs/wazero/internal/wasip1/wasi.go
generated
vendored
Normal file
26
vendor/github.com/tetratelabs/wazero/internal/wasip1/wasi.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Package wasip1 is a helper to remove package cycles re-using constants.
|
||||
package wasip1
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// InternalModuleName is not named ModuleName, to avoid a clash on dot imports.
|
||||
const InternalModuleName = "wasi_snapshot_preview1"
|
||||
|
||||
func flagsString(names []string, f int) string {
|
||||
var builder strings.Builder
|
||||
first := true
|
||||
for i, sf := range names {
|
||||
target := 1 << i
|
||||
if target&f != 0 {
|
||||
if !first {
|
||||
builder.WriteByte('|')
|
||||
} else {
|
||||
first = false
|
||||
}
|
||||
builder.WriteString(sf)
|
||||
}
|
||||
}
|
||||
return builder.String()
|
||||
}
|
Reference in New Issue
Block a user