Commit Graph

475 Commits

Author SHA1 Message Date
Crypt Keeper
282ffc5ced logging: adds memory scope (#1076)
This allows you to specify the memory scope amongst existing logging scopes, both in API and the CLI.

e.g for the CLI.
```bash
$ wazero run --hostlogging=memory,filesystem --mount=.:/:ro cat.wasm
```

e.g. for Go
```go
loggingCtx := context.WithValue(testCtx, experimental.FunctionListenerFactoryKey{},
	logging.NewHostLoggingListenerFactory(&log, logging.LogScopeMemory|logging.LogScopeFilesystem))
```

This is helpful for emscripten and gojs which have memory reset
callbacks. This will be much more interesting once #1075 is implemented.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-29 10:58:59 +02:00
Crypt Keeper
da99a7f5c0 logging: adds exit scope and fixes mtim bug (#1074)
This allows you to specify the exit scope amongst existing logging scopes, both in API and the CLI.

e.g for the CLI.
```bash
$ wazero run --hostlogging=exit,filesystem --mount=.:/:ro cat.wasm
```

e.g. for Go
```go
loggingCtx := context.WithValue(testCtx, experimental.FunctionListenerFactoryKey{},
	logging.NewHostLoggingListenerFactory(&log, logging.LogScopeExit|logging.LogScopeFilesystem))
```

This is helpful to know if the wasm called exit or if it exited
implicitly. This is one of the few host functions that exists in three
places: assemblyscript, gojs and wasi.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-29 08:43:14 +02:00
Crypt Keeper
67662efac9 logging: cleanups and allows comma-separated scope expansion (#1073)
This allows the CLI to use `-hostlogging=filesystem,poll` instead of or
in addition to multiple flags.

This also makes the parameter loggers more debugable by using pointer
receivers. When they are copied, the field names end up garbage in the
debugger.

Finally, this fixes a glitch where we used GOOS=js where we thought we
were using WASI (in cmd tests).

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-29 07:38:53 +02:00
Crypt Keeper
9cf07b4d44 logging: adds poll scope (#1072)
This allows you to specify the poll scope amongst existing logging scopes, both in API and the CLI.

e.g for the CLI.
```bash
$ wazero run --hostlogging=poll --hostlogging=filesystem --mount=.:/:ro cat.wasm
```

e.g. for Go
```go
loggingCtx := context.WithValue(testCtx, experimental.FunctionListenerFactoryKey{},
	logging.NewHostLoggingListenerFactory(&log, logging.LogScopePoll|logging.LogScopeFilesystem))
```

This is particularly helpful to understand side-effects of GC. For
example, in `GOOS=js` GC will trigger events and these have been tricky
to troubleshoot in the past.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-29 06:22:49 +02:00
Crypt Keeper
d944c3c70d logging: adds clock scope (#1071)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-28 19:11:37 +02:00
Crypt Keeper
bd9a791c7a logging: rename crypto scope to random (#1070)
This is to avoid a collision with an emerging wasi-crypto. They will
have both wasi-random and wasi-crypto

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-28 13:15:28 +02:00
Edoardo Vacchi
599c097603 Add -hostlogging=crypto (#1064)
This allows you to specify multiple logging scopes, both in API and the CLI.

e.g for the CLI.
```bash
$ wazero run --hostlogging=crypto --hostlogging=filesystem --mount=.:/:ro cat.wasm
```

e.g. for Go
```go
loggingCtx := context.WithValue(testCtx, experimental.FunctionListenerFactoryKey{},
	logging.NewHostLoggingListenerFactory(&log, logging.LogScopeCrypto|logging.LogScopeFilesystem))
```

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Adrian Cole <adrian@tetrate.io>
2023-01-28 12:51:44 +02:00
Crypt Keeper
1ee161b203 fs: retains original FS paths (#1066)
This changes the logic inside CompositeFS in preparation of re-using the
user-provided input paths for pre-open paths. The main change here is
retaining original insertion order until runtime, then just iterating
backwards then.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-26 22:18:05 -05:00
Takeshi Yoneda
d57bdecadb gojs/test: resolve race under scheduleTimeoutEvent (#1063)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-26 08:26:34 +09:00
Crypt Keeper
cc68f8ee12 fs: adds FSConfig to replace experimental writefs (#1061)
This adds a new top-level type FSConfig, which is configured via
`ModuleConfig.WithFSConfig(fcfg)`. This implements read-only and
read-write directory mounts, something not formally supported before. It
also implements `WithFS` which adapts a normal `fs.FS`. For convenience,
we retain the old `ModuleConfig.WithFS` signature so as to not affect
existing users much. A new configuration for our emerging raw
filesystem, `FSConfig.WithSysfs()` will happen later without breaking
this API.

Here's an example:
```
moduleConfig = wazero.NewModuleConfig().
	// Make the current directory read-only accessible to the guest.
	WithReadOnlyDirMount(".", "/")
	// Make "/tmp/wasm" accessible to the guest as "/tmp".
	WithDirMount("/tmp/wasm", "/tmp")
```

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-25 10:09:40 -10:00
Takeshi Yoneda
3ac53b2192 fuzz: adds target on checking memory state (#1054)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-25 08:16:51 +09:00
Crypt Keeper
cb97d7a488 fs: decouples sysfs from fs.FS and consolidates guest path logic (#1058)
This decouples sysfs.FS from fs.FS by introducing a temporary type
FSHolder, which will be removed when we top-level FSConfig (shortly).

This further reduces complexity by consolidating guest path
configuration into the only type that uses it: CompositeFS.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-23 17:49:51 -10:00
Takeshi Yoneda
c9155b8f2b amd64: fixes memory.fill bug (#1055)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-01-24 08:07:11 +09:00
Crypt Keeper
2a584a8937 fs: renames internal syscallfs package to sysfs and notes RATIONALE (#1056)
It will help for us to rename earlier vs later, and syscallfs will be
laborious, especially after we introduce an FSConfig type and need to
declare a method name that differentiates from normal fs.FS. e.g. WithFS
vs WithSysFS reads nicer than WithSyscallFS, and meanwhile sys is
already a public package.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-23 11:11:35 +08:00
Crypt Keeper
f484f22e47 fs: allows non-root only mounts (#1047)
This adds syntax needed for wasi-testsuite, which mounts a path like
below without mounting anything for "/".

```
-mount=./tests/c/testsuite/fs-tests.dir:/fs-tests.dir
```

Basically, this creates a virtual root path with fake stat.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-19 15:32:24 +08:00
Crypt Keeper
319d6cca62 fs: adds base UnimplementedFS type and unwraps PathError (#1046)
This reduces some boilerplate by extracting UnimplementedFS from the
existing FS implementations, such that it returns ENOSYS. This also
removes inconsistency where some methods on FS returned syscall.Errno
and others PathError.

Note: this doesn't get rid of all PathError, yet. We still need to
create a syscallfs.File type which would be able to do that. This is
just one preliminary cleanup before refactoring out the `fs.FS`
embedding from `syscallfs.DS`.

P.S. naming convention is arbitrary, so I took UnimplementedXXX from
grpc. This pattern is used a lot of places, also proxy-wasm-go-sdk, e.g.
`DefaultVMContext`.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-18 09:37:12 -06:00
Takeshi Yoneda
c331ae4719 Updates Spectest to the latest (Dec 16, 2022) (#1045)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-18 10:13:15 +09:00
Crypt Keeper
3cf29f9f76 fs: adds string for better error experience (#1042)
This prepares for pseudo-root when the CLI doesn't provide one by
improving the error messages in general, as well being consistent about
parameter order.

Signed-off-by: Adrian Cole <adrian@tetrate.io>

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-17 10:01:51 -06:00
Crypt Keeper
3609d74c92 Implements stat device/inode on WASI and GOOS=js (#1041)
This implements stat device and inode for WASI and GOOS=js, though it
does not implement the host side for windows, yet. Doing windows
requires plumbing as the values needed aren't exposed in Go. When we
re-do the syscallfs file type to have a stat method, we can address that
glitch. Meanwhile, I can find no Go sourcebase that does any better,
though the closest is the implementation details of os.SameFile.

I verified this with wasi-testsuite which now passes all but 1 case
which is unrelated (we haven't yet implemented `lseek`).

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-16 22:22:39 -06:00
Crypt Keeper
c222e73847 fs: implements WriterAtOffset for WASI and gojs (#1038)
This implements WriterAtOffset, which supports WASI `fd_pwrite` and gojs
`fs.write` with offset, which is used to implement `syscall.Pwrite`.
I confirmed this passes the corresponding test in wasi-testsuite as
well.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-15 19:52:17 -06:00
Crypt Keeper
713e187796 fs: extracts syscallfs.ReaderAtOffset for WASI and gojs (#1037)
This extracts a utility `syscallfs.ReaderAtOffset()` to allow WASI and
gojs to re-use the same logic to implement `syscall.Pread`.

What's different than before is that if WASI passes multiple iovecs an
emulated `ReaderAt` will seek to the read position on each call to
`Read` vs once per loop. This was a design decision to keep the call
sites compatible between files that implement ReaderAt and those that
emulate them with Seeker (e.g. avoid the need for a read-scoped closer/
defer function). The main use case for emulation is `embed.file`, whose
seek function is cheap, so there's little performance impact to this.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-15 17:30:45 -08:00
Nuno Cruces
59076bccf5 fs: Adds fd_sync (#1026)
Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
2023-01-14 07:16:14 +08:00
Crypt Keeper
105cdcdef7 cli: rewrites compositeFS to syscallfs and adds read-only (:ro) mounts (#1030)
This rewrites compositeFS to syscallfs.FS following wasi-sdk preopen
rules. Notably, this allows use of read-only mounts now.

For example,
```bash
$ GOOS=js GOARCH=wasm bin/go test -c -o template.wasm text/template
$ wazero run -mount=src/text/template:/ -mount=/tmp:/tmp template.wasm -test.v
=== RUN   TestExecute
--- PASS: TestExecute (0.07s)
--snip--
```

This is the first step to native WASI handling of multiple pre-opens.
After this change, it is still the case that there's only one pre-open
FD visible to wasm. A later change will make it possible for WASI to see
multiple pre-opens while `GOOS=js` which doesn't use preopens, remains
on a rootFS.

A future PR may need to add a CLI flag to disable escaping directories,
(e.g. make ../.. EINVAL), similar to `fs.FS` in Go. The simplest way to
allow this is to use a host-side RootFS even in WASI, and wrap that with
a `syscallfs` filename filter.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-13 15:50:11 +08:00
Takeshi Yoneda
2df84c679c ci: adds -skip flag to the race tests (#1023)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-11 12:23:09 +09:00
Crypt Keeper
3fc5392570 fs: fixes windows fstest.FS and consolidates more (#1019)
This works around a known glitch in windows where directory entry stat
doesn't match its corresponding file stat (namely times don't). It
consolidates more test files, in the process, to ensure we are more
likely to trigger issues like this earlier.

Future work will finish the last couple places where we still use go's
fstest.MapFS internally, as well introduce stat tests at the syscallfs
abstraction: right now, most tests are still only defined in WASI.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-10 14:12:18 +08:00
Takeshi Yoneda
b63d4e6dcd Deletes namespace API (#1018)
Formerly, we introduced `wazero.Namespace` to help avoid module name or import conflicts while still sharing the runtime's compilation cache. Now that we've introduced `CompilationCache` `wazero.Namespace` is no longer necessary. By removing it, we reduce the conceptual load on end users as well internal complexity. Since most users don't use namespace, the change isn't very impactful.

Users who are only trying to avoid module name conflict can generate a name like below instead of using multiple runtimes:

```go
moduleName := fmt.Sprintf("%d", atomic.AddUint64(&m.instanceCounter, 1))
module, err := runtime.InstantiateModule(ctx, compiled, config.WithName(moduleName))
```

For `HostModuleBuilder` users, we no longer take `Namespace` as the last parameter of `Instantiate` method: 

```diff
 	// log to the console.
 	_, err := r.NewHostModuleBuilder("env").
 		NewFunctionBuilder().WithFunc(logString).Export("log").
-		Instantiate(ctx, r)
+		Instantiate(ctx)
 	if err != nil {
 		log.Panicln(err)
 	}
```


The following is an example diff a use of namespace can use to keep compilation cache while also ensuring their modules don't conflict:

```diff

 func useMultipleRuntimes(ctx context.Context, cache) {
-	r := wazero.NewRuntime(ctx)
+	cache := wazero.NewCompilationCache()
 
 	for i := 0; i < N; i++ {
-		// Create a new namespace to instantiate modules into.
-		ns := r.NewNamespace(ctx) // Note: this is closed when the Runtime is
+		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().WithCompilationCache(cache))
 
 		// Instantiate a new "env" module which exports a stateful function.
 		_, err := r.NewHostModuleBuilder("env").
```

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-10 14:11:46 +09:00
Crypt Keeper
f1fdeb2565 fs: fixes timebomb on or'd flags with O_RDONLY (#1017)
@achille-roussel mentioned on chat that we have an accident waiting to
happen. This fixes it and backfills the missing test.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-10 08:51:10 +08:00
Takeshi Yoneda
35500f9b85 Introduces Cache API (#1016)
This introduces the new API wazero.Cache interface which can be passed to wazero.RuntimeConfig. 
Users can configure this to share the underlying compilation cache across multiple wazero.Runtime. 
And along the way, this deletes the experimental file cache API as it's replaced by this new API.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
Co-authored-by: Crypt Keeper <64215+codefromthecrypt@users.noreply.github.com>
2023-01-10 09:32:42 +09:00
Adrian Cole
70b87165e7 Skips broken tests from accidental push
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-09 16:47:38 +08:00
Adrian Cole
e1a8ed5a84 Adds fstest and ensures syscallfs implementations pass it
This consolidates test files and ensures our various implementations of
`syscallfs.FS` pass `fstest.TestFS`.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-09 16:21:06 +08:00
Crypt Keeper
8f0967e0e8 fs: Adds tests to prove we allow fs.FS to create new files (#1015)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-09 12:31:02 +08:00
Takeshi Yoneda
e90e1985f3 Moves more func inst fields to comptime objects (#927)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-09 12:25:02 +09:00
Takeshi Yoneda
8e78f3fb04 compiler: deletes function.stackPointerCeil to reduce memory size per instance (#1012)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-06 15:44:57 +09:00
Takeshi Yoneda
6eb1e5d9fb arm64: fixes runtimeValueType for i32.wrap_i64 (#1011)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-06 14:28:48 +09:00
Crypt Keeper
bedde6dc7a Clarifies at semantics and preopen semantics in WASI (#1009)
This adds FS.Path which holds the pre-open path currently only used in
WASI. It also fixes a TODO where we didn't know for sure if the FD
parameter for `path_` functions must always be a pre-open. The TL;DR; is
that usually it is, but it may not be (e.g. in our zig-cc example we can
see any directory FD, not just pre-opens).

Finally, this fixes a bug in our path resolution where we mistook paths
like "foo/foo" for "foo" because we only considered basenames instead of
the full path from the pre-open root.

This also makes pre-open directory lookup lazy because I noticed in
Trivy specifically, this is unnecessary for us to do eagerly, as they
change the FS at runtime per-call. In other words, any value from init
time is invalid later.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-05 18:59:55 +08:00
Crypt Keeper
b90158cdf5 gojs: backfills reference count tests (#1006)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-04 16:20:08 +08:00
Crypt Keeper
f8a33cef8d logging: avoids logging activity to stdio file descriptors (#1007)
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>
2023-01-04 16:04:40 +08:00
Takeshi Yoneda
3ab7e4b36d Ensures user-defined primitive types are usable in host func signatures (#1005)
Ensure primitive types are usable in host func signatures

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-04 15:32:32 +08:00
Crypt Keeper
83e4b66659 Consolidates internal code to syscallfs (#1003)
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>
2023-01-04 13:53:53 +08:00
Takeshi Yoneda
846575d0fa interpreter: removes unneeded fields from func instances (#1004)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-04 11:50:49 +09:00
Crypt Keeper
65c7d9dd1b gojs: stubs all remaining filesystem calls to ENOSYS (#1001)
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>
2023-01-03 15:54:29 +08:00
Takeshi Yoneda
ef3937ffed Simplifies spectest initialization (#1000)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-03 13:22:14 +09:00
Crypt Keeper
8c5106b942 Ensures writes aren't allowed when opening for read (#999)
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>
2023-01-03 12:17:37 +08:00
Takeshi Yoneda
d29b6b011c cache: fixes deadlock in version mismatch (#998)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-01-03 12:17:12 +09:00
Crypt Keeper
4197caa05b Ensures 32-bit platforms build (#996)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-02 11:03:23 +09:00
Crypt Keeper
94491fef0b Implements rename in GOOS=js and WASI (#991)
This implements rename, which is the last function needed to pass TinyGo
os package tests:

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-12-31 16:37:28 +08:00
Crypt Keeper
c9868d89cb Removes internal dependency on fs.FS (#987)
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>
2022-12-31 13:27:54 +08:00
Takeshi Yoneda
2045f71363 enginetest: fixes panic om memory def (#989)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-31 14:27:04 +09:00
Crypt Keeper
da3aa7a5ad Adds ExportedFunctionDefinitions and ExportedMemoryDefinitions (#986)
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>
2022-12-31 13:11:37 +08:00
Takeshi Yoneda
e7018d19ff compiler: force moduleContext initialization after Go function calls (#988)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-31 14:05:30 +09:00