Skip to content

v1.3.0

Compare
Choose a tag to compare
@github-actions github-actions released this 11 Jul 05:15
· 592 commits to main since this release
b361183

wazero 1.3.0 is ready for next month's release of Go 1.21.

The new GOOS=wasip1 GOARCH=wasm will be very popular: It is the first WebAssembly platform for non-browser use. A %.wasm file compiled with Go 1.21 runs fine in wazero. This is thanks to efforts on both sides, CI with gotip and the latest release candidate (1.21rc2).

Go 1.21 is already bringing new developers to WebAssembly: We suggest you unconditionally upgrade in anticipation of demand. Besides this and bug fixes, you may also be interested in our new sys.Stat_t type used for fs.FS integration.

Don't forget to star wazero and any project relevant to you, made by our community. Let's get into the details of what's new!

Go 1.21 ready!

wazero has two relationships to Go 1.21:

  • Can wazero be a dependency of a project compiled with Go 1.21?
  • Can wazero run wasm compiled with Go 1.21's GOOS=wasip1 GOARCH=wasm?

We have made significant progress on both these points. We now run tests on every change with the latest Go 1.21 release candidate and gotip (last commit refreshed weekly).

wazero tests now run with go1.21rc2

wazero includes logic conditional on Go versions, notably to dodge known problems on Windows with Go 1.18. This logic was made more flexible to be forwards compatible with any subsequent version. There was also a platform difference in setting file times, fixed by @evacchi. wazero now runs tests with the latest release candidate on every change, as well as everything it was testing before.

Go no longer skips wasip1 tests if the runtime is wazero

Before, there were a couple of standard library tests skipped on wazero. Notably, these were around non-blocking I/O (os.Stdout and io.Pipe()) and pre-opened sockets. @chriso and @evacchi collaborated to both fix these and also remove the special casing in golang/go. Edo even went beyond to improve code not tested upstream such as named pipes on Windows!

Go and TinyGo share the same heuristics when reading directories

Many compilers use wasi-libc directly to implement functions such as readdir. Go doesn't rely on this, so all logic in GOOS=wasip1 is implemented directly. TinyGo's -target=wasi is a hybrid where some features are implemented in Go and others imported from wasi-libc.

@GeorgeMac noticed some inconsistency when wrapping file systems due to this, where files without inodes were filtered out. Details such as this are not defined in wasip1: while POSIX has something to say, there is murky water. After a long and detailed investigation between @achille-roussel and @codefromthecrypt, three things happened:

  • wazero improved its /RATIONALE.md dramatically around inodes.
  • @achille-roussel championed consistent behavior ending in merged pull requests both to Go and TinyGo.
  • wazero added a new way to control stat info, discussed below.

Custom file stat

fs.FileInfo returned from Stat can optionally include raw info from its Sys() method. In Unix systems, this returns *syscall.Stat_t, allowing access to more timestamps and the file's inode.

However, *syscall.Stat_t is not platform agnostic: its field lengths vary, and the type doesn't exist in Windows or virtual filesystems such as go:embed.

Our first answer to this problem is to define and process a new type, *sys.Stat_t, if returned from info.Sys(). This allows developers to intercept *os.File's Readdir or any fs.File.Stat functions to backfill inode information. For example, if a Readdir returns file info with this, it can set a non-zero inode. This prevents a performance penalty caused by wasi-libc, which would otherwise fan out with a Stat call for each directory entry.

It is understood this first feature is not for most integrators. However, it is an important milestone for filesystem performance and customization. wazero 1.4 will promote our internal writeable API to experimental, allowing full control over filesystem features used by wasip1.

Minor changes

There were numerous small changes in 1.3, thanks to folks who brought them to our attention. Notable call out to @abraithwaite, @ncruces, @leighmcculloch who helped us understand edge cases on resource cleanup and close state concerns.

  • fixed a performance regression on fd_readdir since 1.2.0
  • adds integration tests for TinyGo and GOOS=wasip1 covering custom file systems.
  • added IsClosed() to api.Module for better error handling when a module exits during initialization (_start).
  • numerous improvements in trap code by @ncruces.
  • compiler memory leak mitigation by @inkeliz.
  • experimental: Adds CloseNotifier for custom cleanup tasks.
  • experimental: Removes HTTP and filesystem features only supported in GOOS=js.