adds experimental sys.Errno to begin decoupling from the syscall package (#1582)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2023-07-17 08:13:29 +08:00
committed by GitHub
parent 1dafce0b2a
commit 2f8dd23097
94 changed files with 1591 additions and 1374 deletions

View File

@@ -2,9 +2,8 @@ package gojs
import (
"io"
"syscall"
"github.com/tetratelabs/wazero/internal/platform"
"github.com/tetratelabs/wazero/experimental/sys"
)
// Errno is a (GOARCH=wasm) error, which must match a key in mapJSError.
@@ -62,50 +61,50 @@ var (
// ToErrno maps I/O errors as the message must be the code, ex. "EINVAL", not
// the message, e.g. "invalid argument".
//
// This should match wasi_snapshot_preview1.ToErrno for maintenance ease.
func ToErrno(err error) *Errno {
if err == nil || err == io.EOF {
return nil // io.EOF has no value in GOOS=js, and isn't an error.
}
errno := platform.UnwrapOSError(err)
switch errno {
case syscall.EACCES:
return ErrnoAcces
case syscall.EAGAIN:
return ErrnoAgain
case syscall.EBADF:
return ErrnoBadf
case syscall.EEXIST:
return ErrnoExist
case syscall.EFAULT:
return ErrnoFault
case syscall.EINTR:
return ErrnoIntr
case syscall.EINVAL:
return ErrnoInval
case syscall.EIO:
errno, ok := err.(sys.Errno)
if !ok {
return ErrnoIo
case syscall.EISDIR:
}
switch errno {
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 syscall.ELOOP:
case sys.ELOOP:
return ErrnoLoop
case syscall.ENAMETOOLONG:
case sys.ENAMETOOLONG:
return ErrnoNametoolong
case syscall.ENOENT:
case sys.ENOENT:
return ErrnoNoent
case syscall.ENOSYS:
case sys.ENOSYS:
return ErrnoNosys
case syscall.ENOTDIR:
case sys.ENOTDIR:
return ErrnoNotdir
case syscall.ENOTEMPTY:
case sys.ENOTEMPTY:
return ErrnoNotempty
case syscall.ENOTSUP:
case sys.ENOTSUP:
return ErrnoNotsup
case syscall.EPERM:
case sys.EPERM:
return ErrnoPerm
case syscall.EROFS:
case sys.EROFS:
return ErrnoRofs
default:
return ErrnoIo

View File

@@ -2,8 +2,9 @@ package gojs
import (
"io"
"syscall"
"testing"
"github.com/tetratelabs/wazero/experimental/sys"
)
func TestToErrno(t *testing.T) {
@@ -20,98 +21,98 @@ func TestToErrno(t *testing.T) {
input: io.EOF,
},
{
name: "syscall.EACCES",
input: syscall.EACCES,
name: "sys.EACCES",
input: sys.EACCES,
expected: ErrnoAcces,
},
{
name: "syscall.EAGAIN",
input: syscall.EAGAIN,
name: "sys.EAGAIN",
input: sys.EAGAIN,
expected: ErrnoAgain,
},
{
name: "syscall.EBADF",
input: syscall.EBADF,
name: "sys.EBADF",
input: sys.EBADF,
expected: ErrnoBadf,
},
{
name: "syscall.EEXIST",
input: syscall.EEXIST,
name: "sys.EEXIST",
input: sys.EEXIST,
expected: ErrnoExist,
},
{
name: "syscall.EFAULT",
input: syscall.EFAULT,
name: "sys.EFAULT",
input: sys.EFAULT,
expected: ErrnoFault,
},
{
name: "syscall.EINTR",
input: syscall.EINTR,
name: "sys.EINTR",
input: sys.EINTR,
expected: ErrnoIntr,
},
{
name: "syscall.EINVAL",
input: syscall.EINVAL,
name: "sys.EINVAL",
input: sys.EINVAL,
expected: ErrnoInval,
},
{
name: "syscall.EIO",
input: syscall.EIO,
name: "sys.EIO",
input: sys.EIO,
expected: ErrnoIo,
},
{
name: "syscall.EISDIR",
input: syscall.EISDIR,
name: "sys.EISDIR",
input: sys.EISDIR,
expected: ErrnoIsdir,
},
{
name: "syscall.ELOOP",
input: syscall.ELOOP,
name: "sys.ELOOP",
input: sys.ELOOP,
expected: ErrnoLoop,
},
{
name: "syscall.ENAMETOOLONG",
input: syscall.ENAMETOOLONG,
name: "sys.ENAMETOOLONG",
input: sys.ENAMETOOLONG,
expected: ErrnoNametoolong,
},
{
name: "syscall.ENOENT",
input: syscall.ENOENT,
name: "sys.ENOENT",
input: sys.ENOENT,
expected: ErrnoNoent,
},
{
name: "syscall.ENOSYS",
input: syscall.ENOSYS,
name: "sys.ENOSYS",
input: sys.ENOSYS,
expected: ErrnoNosys,
},
{
name: "syscall.ENOTDIR",
input: syscall.ENOTDIR,
name: "sys.ENOTDIR",
input: sys.ENOTDIR,
expected: ErrnoNotdir,
},
{
name: "syscall.ENOTEMPTY",
input: syscall.ENOTEMPTY,
name: "sys.ENOTEMPTY",
input: sys.ENOTEMPTY,
expected: ErrnoNotempty,
},
{
name: "syscall.ENOTSUP",
input: syscall.ENOTSUP,
name: "sys.ENOTSUP",
input: sys.ENOTSUP,
expected: ErrnoNotsup,
},
{
name: "syscall.EPERM",
input: syscall.EPERM,
name: "sys.EPERM",
input: sys.EPERM,
expected: ErrnoPerm,
},
{
name: "syscall.EROFS",
input: syscall.EROFS,
name: "sys.EROFS",
input: sys.EROFS,
expected: ErrnoRofs,
},
{
name: "syscall.Errno unexpected == ErrnoIo",
input: syscall.Errno(0xfe),
name: "sys.Errno unexpected == ErrnoIo",
input: sys.Errno(0xfe),
expected: ErrnoIo,
},
}

View File

@@ -7,6 +7,7 @@ import (
"syscall"
"github.com/tetratelabs/wazero/api"
experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/gojs/custom"
"github.com/tetratelabs/wazero/internal/gojs/goos"
"github.com/tetratelabs/wazero/internal/gojs/util"
@@ -174,7 +175,7 @@ func (jsfsFstat) invoke(ctx context.Context, mod api.Module, args ...interface{}
func syscallFstat(fsc *internalsys.FSContext, fd int32) (*jsSt, error) {
f, ok := fsc.LookupFile(fd)
if !ok {
return nil, syscall.EBADF
return nil, experimentalsys.EBADF
}
if st, errno := f.File.Stat(); errno != 0 {
@@ -239,11 +240,11 @@ func (jsfsRead) invoke(ctx context.Context, mod api.Module, args ...interface{})
}
// syscallRead is like syscall.Read
func syscallRead(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno syscall.Errno) {
func syscallRead(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno experimentalsys.Errno) {
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
if f, ok := fsc.LookupFile(fd); !ok {
return 0, syscall.EBADF
return 0, experimentalsys.EBADF
} else if offset != nil {
return f.File.Pread(buf, toInt64(offset))
} else {
@@ -282,17 +283,17 @@ func (jsfsWrite) invoke(ctx context.Context, mod api.Module, args ...interface{}
}
// syscallWrite is like syscall.Write
func syscallWrite(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno syscall.Errno) {
func syscallWrite(mod api.Module, fd int32, offset interface{}, buf []byte) (n int, errno experimentalsys.Errno) {
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
if f, ok := fsc.LookupFile(fd); !ok {
errno = syscall.EBADF
errno = experimentalsys.EBADF
} else if offset != nil {
n, errno = f.File.Pwrite(buf, toInt64(offset))
} else {
n, errno = f.File.Write(buf)
}
if errno == syscall.ENOSYS {
errno = syscall.EBADF // e.g. unimplemented for write
if errno == experimentalsys.ENOSYS {
errno = experimentalsys.EBADF // e.g. unimplemented for write
}
return
}
@@ -350,7 +351,7 @@ func (m *jsfsMkdir) invoke(ctx context.Context, mod api.Module, args ...interfac
root := fsc.RootFS()
var fd int32
var errno syscall.Errno
var errno experimentalsys.Errno
// We need at least read access to open the file descriptor
if perm == 0 {
perm = 0o0500
@@ -467,11 +468,11 @@ func (jsfsFchmod) invoke(ctx context.Context, mod api.Module, args ...interface{
// Check to see if the file descriptor is available
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
var errno syscall.Errno
var errno experimentalsys.Errno
if _, ok := fsc.LookupFile(fd); !ok {
errno = syscall.EBADF
errno = experimentalsys.EBADF
} else {
errno = syscall.ENOSYS // We only support functions used in wasip1
errno = experimentalsys.ENOSYS // We only support functions used in wasip1
}
return jsfsInvoke(ctx, mod, callback, errno)
@@ -490,7 +491,7 @@ func (c *jsfsChown) invoke(ctx context.Context, mod api.Module, args ...interfac
_ = args[2] // gid
callback := args[3].(funcWrapper)
errno := syscall.ENOSYS // We only support functions used in wasip1
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
return jsfsInvoke(ctx, mod, callback, errno)
}
@@ -508,11 +509,11 @@ func (jsfsFchown) invoke(ctx context.Context, mod api.Module, args ...interface{
// Check to see if the file descriptor is available
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
var errno syscall.Errno
var errno experimentalsys.Errno
if _, ok := fsc.LookupFile(fd); !ok {
errno = syscall.EBADF
errno = experimentalsys.EBADF
} else {
errno = syscall.ENOSYS // We only support functions used in wasip1
errno = experimentalsys.ENOSYS // We only support functions used in wasip1
}
return jsfsInvoke(ctx, mod, callback, errno)
@@ -531,7 +532,7 @@ func (l *jsfsLchown) invoke(ctx context.Context, mod api.Module, args ...interfa
_ = args[2] // gid
callback := args[3].(funcWrapper)
errno := syscall.ENOSYS // We only support functions used in wasip1
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
return jsfsInvoke(ctx, mod, callback, errno)
}
@@ -548,7 +549,7 @@ func (t *jsfsTruncate) invoke(ctx context.Context, mod api.Module, args ...inter
_ = args[1] // length
callback := args[2].(funcWrapper)
errno := syscall.ENOSYS // We only support functions used in wasip1
errno := experimentalsys.ENOSYS // We only support functions used in wasip1
return jsfsInvoke(ctx, mod, callback, errno)
}
@@ -565,9 +566,9 @@ func (jsfsFtruncate) invoke(ctx context.Context, mod api.Module, args ...interfa
// Check to see if the file descriptor is available
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
var errno syscall.Errno
var errno experimentalsys.Errno
if f, ok := fsc.LookupFile(fd); !ok {
errno = syscall.EBADF
errno = experimentalsys.EBADF
} else {
errno = f.File.Truncate(length)
}
@@ -640,9 +641,9 @@ func (jsfsFsync) invoke(ctx context.Context, mod api.Module, args ...interface{}
// Check to see if the file descriptor is available
fsc := mod.(*wasm.ModuleInstance).Sys.FS()
var errno syscall.Errno
var errno experimentalsys.Errno
if f, ok := fsc.LookupFile(fd); !ok {
errno = syscall.EBADF
errno = experimentalsys.EBADF
} else {
errno = f.File.Sync()
}
@@ -714,11 +715,11 @@ func (s *jsSt) call(_ context.Context, _ api.Module, _ goos.Ref, method string,
panic(fmt.Sprintf("TODO: stat.%s", method))
}
func jsfsInvoke(ctx context.Context, mod api.Module, callback funcWrapper, err syscall.Errno) (interface{}, error) {
func jsfsInvoke(ctx context.Context, mod api.Module, callback funcWrapper, err experimentalsys.Errno) (interface{}, error) {
return callback.invoke(ctx, mod, goos.RefJsfs, maybeError(err), err == 0) // note: error first
}
func maybeError(errno syscall.Errno) error {
func maybeError(errno experimentalsys.Errno) error {
if errno != 0 {
return errno
}

View File

@@ -3,9 +3,9 @@ package gojs
import (
"context"
"path"
"syscall"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/gojs/custom"
"github.com/tetratelabs/wazero/internal/gojs/goos"
"github.com/tetratelabs/wazero/internal/gojs/util"
@@ -65,7 +65,7 @@ func (p *processChdir) invoke(_ context.Context, mod api.Module, args ...interfa
if s, err := syscallStat(mod, newWd); err != nil {
return nil, err
} else if !s.isDir {
return nil, syscall.ENOTDIR
return nil, sys.ENOTDIR
} else {
p.proc.cwd = newWd
return nil, nil

View File

@@ -3,10 +3,10 @@ package gojs
import (
"context"
"fmt"
"syscall"
"time"
"github.com/tetratelabs/wazero/api"
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/internal/gojs/custom"
"github.com/tetratelabs/wazero/internal/gojs/goarch"
"github.com/tetratelabs/wazero/internal/wasm"
@@ -47,9 +47,9 @@ func wasmWrite(_ context.Context, mod api.Module, stack goarch.Stack) {
switch errno {
case 0:
return // success
case syscall.ENOSYS:
case sys.ENOSYS:
return // e.g. unimplemented for write
case syscall.EBADF:
case sys.EBADF:
return // e.g. not opened for write
default:
panic(fmt.Errorf("error writing p: %w", errno))

View File

@@ -3,10 +3,10 @@
package writefs
import (
"syscall"
"github.com/tetratelabs/wazero/experimental/sys"
)
// statFields isn't used outside JS, it is only for compilation
func statFields(string) (atimeNsec, mtimeNsec int64, dev, inode uint64) {
panic(syscall.ENOSYS)
panic(sys.ENOSYS)
}