* experimental: give listener r/o view of globals
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* experimental: add global support to interpreter
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* exp: replace globals proxy with module interface
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* exp: trim down experimental.InternalModule
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Replace globals view slice with constantGlobal
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Fix tests after merge
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Address PR feedback
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Rename methods of experimental.Module
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Run make check
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
* Add WazeroOnlyType to constantGlobal
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
---------
Signed-off-by: Thomas Pelletier <thomas@pelletier.codes>
This makes host functions index consistently on insertion order, rather
than lexicographic order. This helps with ABI such as Emscripten, which
need an expected order.
This also constrains the internal code around host functions to only one
export name. More than one was never used. By restricting this, logic is
simpler and smaller.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Fixes#1211
Previously, host functions are getting api.Module for the "originating" module,
which is the module for api.Function currently invoked, except that the api.Module
is modified by withMemory with the caller's memory instance, therefore there
haven't been no problem for most cases. The only issues were the methods
besides Memory() of api.Module, and this commit fixes them.
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This updates our examples to the latest SDKs as particularly this can
help reveal issues around fan-out stats.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This centralizes filestat logic by making our own `Stat_t` similar to
`syscall.Stat_t`. This exposes utilities in the platform package and
adds a new function `FS.Stat` which avoids having to use `fs.File` to
get the same info. Doing so at the FS abstraction allows us to optimize
how it is implemented internally using portable means (e.g.
`os.StatFile`) or OS-specific means where necessary, e.g. in windows.
This also ensures `platform.OpenFile` returns syscall.Errno and
centralizes error checking with a new `require.EqualErrno` test.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
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>
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>
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>
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>
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>
We originally had a `context.Context` for anything that might be
traced, but it turned out to be only useful for lifecycle and host functions.
For instruction-scoped aspects like memory updates, a context parameter is too
fine-grained and also invisible in practice. For example, most users will use
the compiler engine, and its memory, global or table access will never use go's
context.
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This adds host functions that work on dynamic function tables. These are
only used by emscripten, but require some infrastructure to support it.
I added the least possible to due the task. This also only handles i32
and void returns with up to four parameters as that covers the needs of
PDFium. Future integrations may need more parameters or a mix of floats.
Such use cases should be addressed as they come as otherwise it is a lot
of work for the cartesian product of all combinations.
See 1b0d724fd5/test/passes/post-emscripten.wast
See https://github.com/jerbob92/go-pdfium-wasm
Signed-off-by: Adrian Cole <adrian@tetrate.io>