Developers don't commonly think about 32-bit platforms and in one
instance we broke a release due to this (quickly fixed in pre.7). This
ensures arm and 386, used by dapr and trivy respectively are tested. It
also helps prove these are in use to avoid a later developer removing
support by thinking they aren't.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This avoids logging activity on stdio file descriptors, in order to help
make troubleshooting easier. Usually, there isn't an issue in these, yet
wasm panics are harder to read if there is also logging of the ..
logging.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This consolidates internal code to syscallfs, which removes the fs.FS
specific path rules, except when adapting one to syscallfs. For example,
this allows the underlying filesystem to decide if relative paths are
supported or not, as well any EINVAL related concerns.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This stubs all remaining syscalls for `GOARCH=wasm GOOS=js` to return
ENOSYS, instead of panic'ing. This allows us to see the parameters it
receives.
For example:
```
==> go.syscall/js.valueCall(fs.truncate(path=/tmp/_Go_TestTruncate135754730,length=0))
<== (err=function not implemented,ok=false)
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This masks interfaces returned by `fs.File` so that we don't
accidentally allow writes when opened for reading. This also adds
`syscall.NewReadFS` which can enforce read-only access in general, such
as would be ideal for tests that try to read files from the host root
filesystem (e.g. /etc/passwd).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
As noted in slack, we are unlikley to long term use fs.FS internally.
This ensures we attempt to cast to syscallfs.FS for all I/O by panicing
on fs.Open.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds ExportedFunctionDefinitions and ExportedMemoryDefinitions to
api.Module so that those who can't access CompileModule can see them.
Fixes#839
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This makes the version, arch, os tuple into a subdirectory to help
troubleshooting and cache management in general. The version is left
inside the binary key regardless.
Note: when installing via `go install ./cmd/wazero/...` the version ends
up as `dev`. This helps make that obvious. For example.
```bash
$ wazero version
dev
$ ./build/tinygo test -target wasi -c -o os.wasm os
$ wazero run -cachedir=$HOME/.wazero -mount=.:/ -env=HOME=. os.wasm -test.v
$ find $HOME/.wazero
/Users/adrian/.wazero
/Users/adrian/.wazero/wazero-dev-amd64-darwin
/Users/adrian/.wazero/wazero-dev-amd64-darwin/1f149f4bf475a33023ce33302780bee29ec08e89bd57cfbdf639c65c6009f1a4
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This fixes and backfills tests for open flags, notably O_CREAT. I
verified this with TinyGo tests, which now proceed when attempting to
create new files.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This renames the internal writefs package to syscallfs as it is largely
dependent on syscall signatures. This also implements utimes in gojs.
WASI will be a follow-up change as it requires more infrastructure.
Notably, we also need non-TinyGo tests because TinyGo doesn't yet
support os.Chtimes or corresponding syscalls.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This implements path_(create|remove)_directory path_unlink_file in wasi, particularly needed to use TinyGo tests to verify our interpretation of WASI. Use of this requires the experimental `writefs.DirFS`.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This splits unlink and rmdir from remove, as it is not only more precise
in GOOS=js, but it is also needed to implement wasi. I verified this
works by running go unit tests with logging.
```
==> go.syscall/js.valueCall(fs.open(name=/tmp/TestErrIsNotExist1062486353,flags=,perm=----------))
<== (err=<nil>,fd=10)
==> go.syscall/js.valueCall(fs.fstat(fd=10))
<== (err=<nil>,stat={isDir=true,mode=-rwx------,size=96,mtimeMs=1672285985206})
==> go.syscall/js.valueCall(fs.readdir(name=/tmp/TestErrIsNotExist1062486353))
<== (err=<nil>,dirents=&{[001]})
==> go.syscall/js.valueCall(fs.unlink(path=/tmp/TestErrIsNotExist1062486353/001))
<== (err=is a directory,ok=true)
==> go.syscall/js.valueCall(fs.rmdir(path=/tmp/TestErrIsNotExist1062486353/001))
<== (err=<nil>,ok=false)
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>
The type we use to expose write operations is still evolving. It might
be a single writefs.FS interface, or similar to go where we have an
interface per feature (e.g. writefs.MkdirFS). These choices are all
implementation details for DirFS and won't be settled before the end of
the month version cutoff. Instead, this only exposes the ability to
create a DirFS, not an arbitrary implementation of writefs.FS. This does
so by making `writefs.FS` an internal type.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
We originally exported WASI errno as we originally supported invoking
host functions directly (e.g. without a guest). This was an invalid call
pattern, and we removed that. However, we left the errnos exported even
though the caller of a guest won't ever see them. This prevented us from
re-using them cleanly in features such as logging.
This moves all constants including function names and flag enums
internal so that there is less duplication between logging and
implementation of wasi functions. This also helps in reference searches,
as we can analyze uses of a particular function name.
The only constant left exported is the module name, as there's a use
case for that (overriding implementations via FunctionBuilder).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds writefs.FS, allowing functions to create and delete files.
This begins by implementing them on `GOARCH=js GOOS=wasm`. The current
status is a lot farther than before, even if completing write on WASI is
left for a later PR (possibly by another volunteer).
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This uses logging infrastructure introduced in #938 to show
paths and certain result parameters. While further tuning is expected,
the main thing this does is show which paths are affected by syscalls.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This changes the listener signature to accept context and calling
module, so that all possible parameters and results can be logged. This
also changes the logging listener to make parameters visible when
logging results.
This infrastructure supports some helpful use cases, such as logging
WASI result parameters, such as the prestat path, which is only knowable
after the function has been called. The context parameter supposed
reading results of gojs functions, which are stored host-side in a go
context object.
Future pull requests will complete this as well backfill unit tests.
This is raised independently mainly to keep the PR size down of the
upcoming filesystem logger.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
`GOARCH=wasm GOOS=js` defines parameter names in go source, and they are
indirectly related to the wasm parameter "sp". This creates a pseudo
name section so that we can access the parameter names. The alternative
would be adding a hack to normal FunctionDefinition, only used for gojs.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This refactors GOOS and GOARCH specific code into their own packages.
This allows logging interceptors to be built without cyclic package
dependencies.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This makes it easier to do maintenance by hiding the implementation
details of using a proxy module to test host modules. What happens is we
skip logging of these proxy modules, which makes it easier to see what
log affects a change has.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This changes the CLI to detect if GOOS=js is likely in use and switches
accordingly. This makes it eaiser to find bugs and may eventually lead
to go being able to swap out node.js for wazero.
Note: GOOS=js a.k.a. gojs isn't complete, yet, so this helps identify
that as well. For example, similar to WASI there's no suppor for mkdir
yet.
```bash
$ GOOS=js GOARCH=wasm go test -o os.wasm -c os
$ wazero run os.wasm -test.v
```
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Allows wasm to close stdio file descriptors
This allows wasm to close stdio file descriptors such as STDOUT(1).
This will not close the underlying host resource as that would break a
lot of folks doing logging to the console.
Fixes#953
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds benchmarks from lib sodium, but the results are hard to interpret. We may need to recompile them using zig so that we can export a function instead of using WASI to do it. Right now, we can't really see performance of functions because other runtimes aren't designed to re-instantiate like ours.
This only compares against wasmtime as that's the only runtime besides
ours that is safe to re-instantiate.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds a `compile` command and a `-cachedir` option to expose our
compilation cache to end users. This allows substantial speedup
especially for large wasm.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Anuraag Agrawal <anuraaga@gmail.com>