Adds more links to rationale about start functions (#1569)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2023-07-07 16:27:39 +08:00
committed by GitHub
parent 2b35d93612
commit 0d0db0e12f
2 changed files with 45 additions and 5 deletions

View File

@@ -414,12 +414,49 @@ In reflection, this approach worked well for the nearly 1.5 year period leading
to version 1.0. We've only had to create a single sub-configuration, `FSConfig`,
and it was well understood why when it occurred.
## Why does InstantiateModule call "_start" by default?
We formerly had functions like `StartWASICommand` that would verify preconditions and start WASI's "_start" command.
However, this caused confusion because both many languages compiled a WASI dependency, and many did so inconsistently.
## Why does `ModuleConfig.WithStartFunctions` default to `_start`?
That said, if "_start" isn't called, it causes issues in TinyGo, as it needs this in order to implement panic. To deal
with this a different way, we have a configuration to call any start functions that exist, which defaults to "_start".
We formerly had functions like `StartWASICommand` that would verify
preconditions and start WASI's `_start` command. However, this caused confusion
because both many languages compiled a WASI dependency, and many did so
inconsistently.
The conflict is that exported functions need to use features the language
runtime provides, such as garbage collection. There's a "chicken-egg problem"
where `_start` needs to complete in order for exported behavior to work.
For example, unlike `GOOS=wasip1` in Go 1.21, TinyGo's "wasi" target supports
function exports. So, the only way to use FFI style is via the "wasi" target.
Not explicitly calling `_start` before an ABI such as wapc-go, would crash, due
to setup not happening (e.g. to implement `panic`). Other embedders such as
Envoy also called `_start` for the same reason. To avoid a common problem for
users unaware of WASI, and also to simplify normal use of WASI (e.g. `main`),
we added `_start` to `ModuleConfig.WithStartFunctions`.
In cases of multiple initializers, such as in wapc-go, users can override this
to add the others *after* `_start`. Users who want to explicitly control
`_start`, such as some of our unit tests, can clear the start functions and
remove it.
This decision was made in 2022, and holds true in 2023, even with the
introduction of "wasix". It holds because "wasix" is backwards compatible with
"wasip1". In the future, there will be other ways to start applications, and
may not be backwards compatible with "wasip1".
Most notably WASI "Preview 2" is not implemented in a way compatible with
wasip1. Its start function is likely to be different, and defined in the
wasi-cli "world". When the design settles, and it is implemented by compilers,
wazero will attempt to support "wasip2". However, it won't do so in a way that
breaks existing compilers.
In other words, we won't remove `_start` if "wasip2" continues a path of an
alternate function name. If we did, we'd break existing users despite our
compatibility promise saying we don't. The most likely case is that when we
build-in something incompatible with "wasip1", that start function will be
added to the start functions list in addition to `_start`.
See http://wasix.org
See https://github.com/WebAssembly/wasi-cli
## Runtime == Engine+Store
wazero defines a single user-type which combines the specification concept of `Store` with the unspecified `Engine`

View File

@@ -490,6 +490,8 @@ type ModuleConfig interface {
// WithStartFunctions configures the functions to call after the module is
// instantiated. Defaults to "_start".
//
// Clearing the default is supported, via `WithStartFunctions()`.
//
// # Notes
//
// - If a start function doesn't exist, it is skipped. However, any that
@@ -500,6 +502,7 @@ type ModuleConfig interface {
// - Start functions commonly exit the module during instantiation,
// preventing use of any functions later. This is the case in "wasip1",
// which defines the default value "_start".
// - See /RATIONALE.md for motivation of this feature.
WithStartFunctions(...string) ModuleConfig
// WithStderr configures where standard error (file descriptor 2) is written. Defaults to io.Discard.