Releases: tetratelabs/wazero
v1.8.1
Hiya folks - another small wazero release v1.8.1 has arrived! This time is mainly about bug fixes thanks to the community members!
Bug fixes
- 111c51a Fix descriptor.Table buffer growth calc (#2311) by @emcfarlane
- b468ada compiler: ResolveImportedFunction should infer the typeID from the importing module (#2314) @evacchi
- dc058c0 sysfs: reopening file doesn't update fd (#2319) @ncruces
Behavioral changes
- 178eefe sysfs: disallow absolute symlinks (#2324) @ncruces - this is for better security.
- 1353ca2 experimental: allow custom memory allocator Reallocate to fail (#2315) @ncruces
Examples fixes
- 5848888 Show close for concurrent-instantiation example (#2309) @emcfarlane
- 51aba37 example: fixes deallocate error in Rust (#2327) @mathetake thanks to the report by @thacoon
Enjoy! 🍁
v1.8.0
Hi wazero friends, been a while! The new release of wazero v1.8.0 has arrived 🎉 🏝️☀️ 🍺
This release has happened intentionally right after the Go 1.23 release. @ncruces worked so hard (#2301), and updated our codebase to make it up-to-date with the new Go versions. Notably, since this release, we set our floor Go version to 1.21 (-2 from the latest) following our support policy.
The following is the brief summary of what's included in this release!
Experimental feature: importResolver
A new wazero friend @bep from the Hugo community came up with an exciting way to "link" modules dynamically/anonymously,
which we call "ImportResolver". The feature was implemented in #2298, and available under experimental package.
If you are interested please give it a shot, and give us your feedback!
Emscripten update
@jerbob92 found out that a breaking change was introduced in Emscripten 3.1.57+, and worked to make our emscripten
package to support these recent versions. Unfortunately, the older emscriptens are not supported anymore, so users
are encouraged to update their Emscripten version. #2290
Bug fixes
- threads: lock around invocations of memory.Grow (#2279) @anuraaga
- amd64: fixes lowerSqmulRoundSat (#2260) @mathetake
Compilation perf improvements
Just like the recent previous releases, @mathetake worked hard to make compilation faster.
Unfortunately, we don't have a concrete number to showcase here, but both Interpreter and Compiler
engines now runs really faster compared to the previous releases during compilation without affecting the runtime performance.
If you are interested in the latest updates and discussion around this topic, feel free to follow the thread in #2182.
Others
v1.7.3
Time to celebrate the new wazero release! This time has not only the important bugs fixes just like before, but more importantly comes with the drastic "compilation time" performance improvements!
Bug fixes
- Various WASI related bug fixes contributed by @yagehu #2244 #2229 #2223
- Syscall compatibility fix on Windows by @ncruces #2218
- api.Memory.Grow call bug introduced in v1.7.0 by @mathetake #2216 (thanks to @mark-pictor-csec for reporting)
Compilation perf improvements
@mathetake worked so hard to improve the compilation performance which some users had raised issue about since the release of the optimizing compiler in 1.7.0. The idea is that even though this is partly because it is "optimizing", there are still rooms for improvements in its codebase to use less CPU/memory.
The below is the compilation time benchmark on the various standard library tests for Zig, Go and TinyGo compared to the previous v1.7.2. You can see the huge results up to like 50% faster and ~50% less memory usage. Note that this doesn't affect any runtime performance -- that means your code runs just exactly like before while having faster compilation!😎
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero/internal/integration_test/stdlibs
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
Zig/Compile/test-opt.wasm-10 4.872 ± 2% 3.389 ± 3% -30.44% (p=0.001 n=7)
Zig/Compile/test.wasm-10 5.926 ± 2% 4.162 ± 1% -29.76% (p=0.001 n=7)
TinyGo/Compile/container_heap.test-10 677.2m ± 0% 306.3m ± 1% -54.76% (p=0.001 n=7)
TinyGo/Compile/container_list.test-10 673.2m ± 1% 309.3m ± 8% -54.05% (p=0.001 n=7)
TinyGo/Compile/container_ring.test-10 665.1m ± 1% 299.5m ± 0% -54.97% (p=0.001 n=7)
TinyGo/Compile/crypto_des.test-10 686.4m ± 0% 311.6m ± 0% -54.61% (p=0.001 n=7)
TinyGo/Compile/crypto_md5.test-10 685.5m ± 1% 312.7m ± 4% -54.38% (p=0.001 n=7)
TinyGo/Compile/crypto_rc4.test-10 666.5m ± 0% 297.9m ± 0% -55.31% (p=0.001 n=7)
TinyGo/Compile/crypto_sha1.test-10 683.7m ± 0% 310.1m ± 0% -54.65% (p=0.001 n=7)
TinyGo/Compile/crypto_sha256.test-10 692.0m ± 1% 315.0m ± 2% -54.48% (p=0.001 n=7)
TinyGo/Compile/crypto_sha512.test-10 692.7m ± 0% 316.6m ± 1% -54.29% (p=0.001 n=7)
TinyGo/Compile/encoding_ascii85.test-10 680.6m ± 1% 309.3m ± 1% -54.55% (p=0.001 n=7)
TinyGo/Compile/encoding_base32.test-10 1637.6m ± 1% 650.8m ± 0% -60.26% (p=0.001 n=7)
TinyGo/Compile/encoding_csv.test-10 740.0m ± 1% 333.5m ± 0% -54.92% (p=0.001 n=7)
TinyGo/Compile/encoding_hex.test-10 708.7m ± 3% 320.9m ± 0% -54.72% (p=0.001 n=7)
TinyGo/Compile/go_scanner.test-10 773.2m ± 1% 347.1m ± 6% -55.11% (p=0.001 n=7)
TinyGo/Compile/hash.test-10 951.8m ± 1% 410.8m ± 0% -56.84% (p=0.001 n=7)
TinyGo/Compile/hash_adler32.test-10 665.8m ± 1% 297.5m ± 0% -55.32% (p=0.001 n=7)
TinyGo/Compile/hash_crc64.test-10 893.9m ± 1% 385.1m ± 1% -56.92% (p=0.001 n=7)
TinyGo/Compile/hash_fnv.test-10 695.8m ± 2% 312.4m ± 0% -55.10% (p=0.001 n=7)
TinyGo/Compile/html.test-10 2.426 ± 1% 2.012 ± 1% -17.07% (p=0.001 n=7)
TinyGo/Compile/internal_itoa.test-10 662.5m ± 1% 296.0m ± 1% -55.32% (p=0.001 n=7)
TinyGo/Compile/internal_profile.test-10 893.6m ± 1% 417.9m ± 0% -53.24% (p=0.001 n=7)
TinyGo/Compile/math.test-10 821.1m ± 0% 398.4m ± 0% -51.48% (p=0.001 n=7)
TinyGo/Compile/math_cmplx.test-10 701.7m ± 0% 338.8m ± 1% -51.71% (p=0.001 n=7)
TinyGo/Compile/net.test-10 755.4m ± 1% 356.5m ± 3% -52.81% (p=0.001 n=7)
TinyGo/Compile/net_http_internal_ascii.test-10 661.5m ± 1% 296.8m ± 2% -55.14% (p=0.001 n=7)
TinyGo/Compile/net_mail.test-10 927.1m ± 2% 398.9m ± 2% -56.97% (p=0.001 n=7)
TinyGo/Compile/os.test-10 754.9m ± 0% 370.5m ± 0% -50.92% (p=0.001 n=7)
TinyGo/Compile/path.test-10 677.1m ± 1% 305.5m ± 1% -54.88% (p=0.001 n=7)
TinyGo/Compile/reflect.test-10 842.3m ± 3% 416.7m ± 1% -50.53% (p=0.001 n=7)
TinyGo/Compile/sync.test-10 693.8m ± 4% 315.3m ± 2% -54.55% (p=0.001 n=7)
TinyGo/Compile/testing.test-10 766.8m ± 6% 338.6m ± 0% -55.85% (p=0.001 n=7)
TinyGo/Compile/testing_iotest.test-10 717.6m ± 2% 322.7m ± 0% -55.03% (p=0.001 n=7)
TinyGo/Compile/text_scanner.test-10 728.2m ± 1% 329.8m ± 0% -54.71% (p=0.001 n=7)
TinyGo/Compile/unicode.test-10 686.1m ± 3% 312.6m ± 1% -54.44% (p=0.001 n=7)
TinyGo/Compile/unicode_utf16.test-10 673.0m ± 1% 312.1m ± 3% -53.63% (p=0.001 n=7)
TinyGo/Compile/unicode_utf8.test-10 681.9m ± 1% 308.5m ± 2% -54.76% (p=0.001 n=7)
Wasip1/Compile/src_archive_tar.test-10 3.203 ± 0% 1.938 ± 2% -39.49% (p=0.001 n=7)
Wasip1/Compile/src_bufio.test-10 1.949 ± 3% 1.297 ± 0% -33.46% (p=0.001 n=7)
Wasip1/Compile/src_bytes.test-10 2.009 ± 0% 1.339 ± 0% -33.37% (p=0.001 n=7)
Wasip1/Compile/src_context.test-10 2.153 ± 3% 1.444 ± 1% -32.92% (p=0.001 n=7)
Wasip1/Compile/src_encoding_ascii85.test-10 1.788 ± 2% 1.160 ± 1% -35.12% (p=0.001 n=7)
Wasip1/Compile/src_encoding_asn1.test-10 2.037 ± 2% 1.334 ± 1% -34.50% (p=0.001 n=7)
Wasip1/Compile/src_encoding_base32.test-10 1.829 ± 1% 1.203 ± 0% -34.20% (p=0.001 n=7)
Wasip1/Compile/src_encoding_base64.test-10 1.845 ± 0% 1.212 ± 0% -34.31% (p=0.001 n=7)
Wasip1/Compile/src_encoding_binary.test-10 1.881 ± 1% 1.241 ± 0% -34.04% (p=0.001 n=7)
Wasip1/Compile/src_encoding_csv.test-10 1.840 ± 0% 1.208 ± 0% -34.33% (p=0.001 n=7)
Wasip1/Compile/src_encoding_gob.test-10 2.430 ± 0% 1.647 ± 0% -32.22% (p=0.001 n=7)
Wasip1/Compile/src_encoding_hex.test-10 1.782 ± 0% 1.180 ± 3% -33.78% (p=0.001 n=7)
Wasip1/Compile/src_encoding_json.test-10 5.244 ± 4% 3.496 ± 2% -33.33% (p=0.001 n=7)
Wasip1/Compile/src_encoding_pem.test-10 2.312 ± 3% 1.530 ± 4% -33.83% (p=0.001 n=7)
Wasip1/Compile/src_encoding_xml.test-10 2.129 ± 0% 1.435 ± 1% -32.58% (p=0.001 n=7)
Wasip1/Compile/src_errors.test-10 1.828 ± 1% 1.202 ± 1% -34.24% (p=0.001 n=7)
Wasip1/Compile/src_expvar.test-10 2.656 ± 0% 1.790 ± 1% -32.60% (p=0.001 n=7)
Wasip1/Compile/src_flag.test-10 1.951 ± 0% 1.309 ± 0% -32.93% (p=0.001 n=7)
Wasip1/Compile/src_fmt.test-10 1.992 ± 2% 1.322 ± 0% -33.63% (p=0.001 n=7)
Wasip1/Compile/src_hash.test-10 1.838 ± 1% 1.187 ± 1% -35.40% (p=0.001 n=7)
Wasip1/Compile/src_hash_adler32.test-10 1.779 ± 3% 1.150 ± 0% -35.39% (p=0.001 n=7)
Wasip1/Compile/src_hash_crc32.test-10 1.764 ± 6% 1.164 ± 0% -34.05% (p=0.001 n=7)
Wasip1/Compile/src_hash_crc64.test-10 1.754 ± 2% 1.154 ± 0% -34.20% (p=0.001 n=7)
Wasip1/Compile/src_hash_fnv.test-10 1.829 ± 3% 1.162 ± 1% -36.49% (p=0.001 n=7)
Wasip1/Compile/src_hash_maphash.test-10 1.812 ± 7% 1.172 ± 0% -35.36% (p=0.001 n=7)
Wasip1/Compile/src_io.test-10 1.984 ± 2% 1.284 ± 0% -35.30% (p=0.001 n=7)
Wasip1/Compile/src_io_fs.test-10 1.981 ± 2% 1.276 ± 0% -35.62% (p=0.001 n=7)
Wasip1/Compile/src_io_ioutil.test-10 1.890 ± 4% 1.189 ± 0% -37.09% (p=0.001 n=7)
Wasip1/Compile/src_log.test-10 1.800 ± 4% 1.170 ± 0% -35.00% (p=0.001 n=7)
Wasip1/Compile/src_log_syslog.test-10 1.837 ± 4% 1.157 ± 0% -37.04% (p=0.001 n=7)
Wasip1/Compile/src_maps.test-10 1.794 ± 4% 1.169 ± 0% -34.86% (p=0.001 n=7)
Wasip1/Compile/src_math.test-10 1.975 ± 3% 1.276 ± 2% -35.39% (p=0.001 n=7)
Wasip1/Compile/src_math_big.test-10 3.586 ± 4% 2.443 ± 2% -31.87% (p=0.001 n=7)
Wasip1/Compile/src_math_bits.test-10 1.834 ± 3% 1.210 ± 6% -34.01% (p=0.001 n=7)
Wasip1/Compile/src_math_cmplx.test-10 1.876 ± 3% 1.221 ± 2% -34.91% (p=0.001 n=7)
Wasip1/Compile/src_math_rand.test-10 2.956 ± 2% 1.942 ± 4% -34.31% (p=0.001 n=7)
Wasip1/Compile/src_mime.test-10 1.942 ± 3% 1.307 ± 4% -32.69% (p=0.001 n=7)
Wasip1/Compile/src_mime_multipart.test-10 2.244 ± 2% 1.482 ± 7% -33.95% (p=0.001 n=7)
Wasip1/Compile/src_mime_quotedprintable.test-10 1.927 ± 3% 1.216 ± 0% -36.89% (p=0.001 n=7)
Wasip1/Compile/src_os.test-10 2.531 ± 3% 1.635 ± 3% -35.38% (p=0.001 n=7)
Wasip1/Compile/src_os_exec.test-10 4.691 ± 1% 3.196 ± 2% -31.87% (p=0.001 n=7)
Wasip1/Compile/src_os_signal.test-10 1.792 ± 3% 1.142 ± 1% -36.27% (p=0.001 n=7)
Wasip1/Compile/src_os_user.test-10 1.795 ± 3% 1.172 ± 0% -34.68% (p=0.001 n=7)
Wasip1/Compile/src_path.test-10 1.805 ± 3% 1.159 ...
v1.7.2
Hi all, another release for wazero has arrived! This v1.7.2 is just as boring as the previous v1.7.1, but includes important bug fixes!
Notably,
- On amd64, wazero properly saves the potentially clobbered registers during
memory.{copy,init,fill}
instructions after #2202, by @mathetake. - For very large stack traces with lots of inlined function calls, previously it included the
omitted frames...
comment in the wrong position, which is fixed in #2199 by @mathetake. - A race condition during the concurrent compilation has been fixed in #2194 by @mathetake
- The custom memory allocator introduced in v1.7.1 has been fixed and now sets the memory capacity properly in #2189 by @anuraaga
Enjoy! 👯 🕺 💃
v1.7.1
Hiya folks, time to celebrate the new wazero release again! The last release 1.7.0 was such a blast so this new 1.7.1 is a little bit boring compared to it, but it still has some niceties!
This patch release has basically two major things: various bug fixes and experimental memory allocation API!
Bug fixes
Since the release of 1.7.0, several community members (@jerbob92, @anuraaga and @davidmdm) tried the new optimizing compiler and reported some bugs. @mathetake and @evacchi worked on the fix and all the reported bugs were removed. Notably, the arm64 compiler has become more robust against huge binaries like the ones produced by the Go official compiler, in addition to a corner case in the bounds check elimination optimization pass applied to both arm64 and amd64.
Experimental Memory Allocator API
The experimental Memory Allocator API has been added to our experimental friends by @ncruces in collaboration with @achille-roussel. This allows you to control how to allocate the linear memory of Wasm instance. For instance, you can use a memory mapped buffer as a Wasm linear memory. This is highly advanced feature hence requires a lot of detailed knowledge on how Wasm module works. If this is something interesting to you, we highly recommend to talk to @ncruces who is an expert in here ;)
Other Contributions
- it is now possible to successfully build wazero with TinyGo compiler thanks to the contributions by @deadprogram and @orsinium
- @ncruces helped clean up the dead codes and experimental packages.
v1.7.0
Welcome to wazero 1.7: the release that upgrades like a minor, but feels like a major!
It's finally time for the long-awaited, final release of our brand new optimizing compiler. This is such a big deal that we are celebrating it at Wasm I/O 2024 with another round of wonderful lightning talks from wazero users like we did in 2023. In fact, even this release is being tagged during the event! Stay tuned on our usual channels to see the recording:
- Follow the #wazero hashtag on Twitter
- Join the #wazero channel on the Gophers Slack
wazero optimizes machine code compiled from wasm
Translating Wasm bytecode into machine code can take multiple forms. An optimizing compiler performs multiple nontrivial transformations on the input code, ultimately producing more efficient ("optimized") code.
In 1.7 we replaced our internal wasm compiler with an optimizing one. This means it is a drop-in: you don’t need to do anything to use it. If interested in compiler design, please read the docs, contributed by @evacchi.
As for performance improvements, we have come to expect a run-time boost ranging from 10% to even 60%, with 30-40% being the average. Notably:
- @ncruces' fork of coremark shows an improved score of 15265 vs 9591, i.e. about +60% on arm64 (Apple M1 Pro)
- mercari/grpc-federation improvements between 4-10% on their Wasm extensions to the Common Extension Language
- kubernetes-sigs/kube-scheduler-wasm-extension sees an average of >40% decrease on schedule lifecycle overhead
- @achille-roussel contributed some numbers on the Go standard library (
GOOS=wasip1
) showing at least 30% improvements on thesyscall
,compress/flate
(gzip) andencoding/json
packages, with peaks of 60% (especially in data throughput).
While a major improvement, we decided against calling this version 2.0. If we did, we would cause library dependency lockups due to go imports needing a ‘/v2’. We take backwards compatibility seriously, so couldn’t do that to you!
As usual, @mathetake owns the lionshare of the contributions, with @evacchi helping along the way, especially on the new amd64
backend. Notably, @achille-roussel also contributed a performance improvement to the compiler (#2026) and @ncruces helped in many ways with testing and verifying the implementation, validating (among other things) against his library go-sqlite3.
Note: an optimizing compiler does more work, so it takes longer. Production use of wazero should always compile wasm during initialization to avoid slowing down function runtime.
Experimental: Wasm Threads Spec
The Wasm Threads spec introduces instructions to explicitly share memory between modules, and new operations for atomic memory access. Compilers may use this feature for concurrent threads of execution. For instance @anuraaga’s Go ports of protoc plugins needed atomic instruction support to compile to Wasm.
1.7 concludes a long journey started with @anuraaga's first PR #1899 and continued with @mathetake occasionally tag-teaming, especially to support in the new compiler; @ncruces assisted with reviewing.
You can enable Wasm Threads support by setting the corresponding flag:
// Threads support must be enabled explicitly in addition to standard V2 features.
cfg := wazero.NewRuntimeConfig().
WithCoreFeatures(api.CoreFeaturesV2 | experimental.CoreFeaturesThreads)
For a usage example see features_example_test.go
Experimental: Snapshot/Restore
The Snapshot/Restore experimental feature saves the state of a wasm function and restores it later. This feature has been contributed by @anuraaga to implement exception handling in wasilibs/go-pgquery
You can enable snapshot/restore by setting the context flag:
// Enable experimental snapshotting functionality by setting it to context. We use this
// context when invoking functions, indicating to wazero to enable it.
ctx = context.WithValue(ctx, experimental.EnableSnapshotterKey{}, struct{}{})
For a detailed example see experimental/checkpoint_example_test.go and for further details read PR #1808.
Notably, the Thread Spec and Snapshot/Restore were originally developed as part of the wazerox friendly fork to support wasilibs. With both features making it into this release, @anuraaga could proceed with archiving wazerox: another win from wazero 1.7!
Other changes
- Experimental support for
GOOS=gojs
has been dropped (@mathetake, #2027) - @orsinium contributed a fix to a test (
TestErrorBuilderGoRuntimeError
, #2142) - @karelbilek has started to extensively test our VFS implementation, contributed a tiny fix in #2100 and reported a few documentation issues.
Thanks everyone for making wazero awesomer and awesomer!
v1.7.0-pre.1
v1.6.0
Hey, gophers! Do you know what time it is? It is that time of the year again! That time when we all gather together to share our time with friends and family to celebrate ANOTHER AWESOME WAZERO RELEASE!
Notably, this release includes the first public experimental release of the long-awaited, highly-requested multi-pass optimizing compiler! Keep reading for more details!
A huge thanks to all the contributors, old and new, and always remember that all the developers hang out at the Gophers Slack in the #wazero channel; and if you haven’t already you can star our repo. You know, Santa is making a list, and checking it twice.
It’s been a while since v1.5.0, but we promise v1.6.0 was worth the wait! Fun facts about v1.6.0:
- This is the best release since the last one.
- This release is 100% richer in holiday cheer. ❄️🎄
- Mulled wine is a fantastic developer productivity boost.
The Optimizing Compiler
Jokes aside, we have a lot to cheer about! The lion share of this release is obviously our brand new optimizing compiler (codename “wazevo”) now available as an experimental feature for arm64 (#1496)!
@mathetake led the design and implementation. Work started this summer, and it has evolved in a few iterations over the last months. Initial focus has been on general abstract infrastructure and support to the arm64 instruction set as our first compilation target. @evacchi contributed to the arm64 backend with special focus on the SIMD instructions, and @achille-roussel helped improve the initial register allocator (this was then further evolved and eventually overhauled again by @mathetake). @ncruces contributed with suggestions and testing.
We held off a few releases to polish this new compiler and gain more confidence in the implementation. In this first public release, the optimizing compiler is only available for arm64. The journey to supporting amd64 is set to begin soon with @evacchi leading the effort.
The new compiler has been, as usual, extensively tested against the Wasm spec, our own unit tests, and against the standard libraries of TinyGo, Go and Zig; and of course it has also been hardened through hours-long fuzzing.
You can enable the optimizing compiler by replacing wazero.NewRuntimeConfigCompiler()
or wazero.NewRuntimeConfig()
with the new experimental API as follows:
- c := wazero.NewRuntimeConfigCompiler()
+ c := opt.NewRuntimeConfigOptimizingCompiler()
- c := wazero.NewRuntimeConfig()
+ c := opt.NewRuntimeConfigOptimizingCompiler()
The CLI is now also exposing an experimental flag -optimizing-compiler
:
wazero run -optimizing-compiler myapp.wasm
The optimizing compiler is an experimental feature so we welcome your input. It is also a work in progress: we implemented only a few optimization passes, guiding our choices through testing and benchmarking.
It is worth noting that WebAssembly is an interesting beast: since it is a compilation target, most compilers generate pre-optimized output; therefore, some traditional optimization passes may surprisingly only add build-time overhead and produce no observable improvement. However, our work there is far from being done: more optimization passes can be added; we invite you to do your experiments and bring your own suggestions. For instance, among others, we currently implement forms of dead-code elimination, and bounds-checking eliminations.
In your experiments, you should also expect the CompileModule
phase to take a while longer than the old compiler: the difference may be noticeable with large modules; but you can still cache the result, so you can pay this cost only once. The good news is that, in our tests, the run-time should always visibly improve. Interestingly enough, there are also some cases where both compile-time and run-time have improved: this might be the case when the input module is not pre-optimized, and the dead-code elimination procedures kick in.
For instance, the Zig standard library is about 2x quicker to compile and 4x faster to run than the old compiler. However, a pre-optimized test binary (e.g. pre-processed using Binaryen’s wasm-opt
) will be much faster to build on the old compiler, but the new compiler will still produce 2x faster code. This is fully expected because the old compiler does a straightforward translation from input Wasm to native code: therefore, processing time tends to be low; but if the input is large, the generated output will be large. The new compiler is smarter, in that it is able to drop all the irrelevant code sections; in fact, processing time is about the same on both an optimized and unoptimized binary.
The bottom line is: if you control the Wasm binary, run it through wasm-opt
and compare the result for your workload!
Deprecations
- @mathetake removed the Parameters API from StackIterator (#1716) as this feature hasn't been used in practice, and it is also difficult to implement in the optimizing compiler.
- @Danlock contributed (#1782) some deprecation warnings to
emscripten.Instantiate
and related functions in favor ofemscripten.InstantiateForModule
. Examples have been updated accordingly. This is also @Danlock’s first contribution! Cheers!
Other Contributions
Speaking of first-timers, let’s welcome them all:
- @Danlock’s contributed the
emscripten
deprecation warnings mentioned above. - @valpackett contributed performance and reliability improvements, solving a potential memory leak and a crash when caching is enabled (#1815, #1816).
- @yagehu contributed a few important fixes to our WASI implementation, especially regarding parameter types and error values (#1863, #1866, #1871).
Cheers to all of you! You are helping make wazero awesome!
Now onto the veterans!
- @anuraaga contributed a fix to our CI (#1711), but he is also continuing his work improving wazero on his friendly fork wazerox. Keep an eye on it for some bleeding edge features that might eventually end up upstream!
- @ncruces made sure that wazero builds successfully when GOOS=aix (#1723) for all you mainframe lovers
- Zig is now pinned to version 0.11 and we are testing against TinyGo 0.30 on CI (@mathetake, #1729 and #1745)
- golangci-lint has been updated to v1.55.2 for compatibility with the latest Go point release (@evacchi, #1879)
Finally, we also welcome to the community pages:
v1.5.0
Hey, do you know what time is it? ⏰ Yes! Time for another wazero release! 🎉
Notably, as previously announced, this release drops support to Go 1.18. But you must be here for the goodies! Don't you worry, we have you covered: there's a whole lot of updates especially for you Emscripten fanatics!
Time flies when you are having fun: WasmCon 2023 is only a few days away (5-6 September). Remember, our very own @evacchi will be there to talk about wazero, so if you are going to be there, don't be shy and say hi!
Improved Emscripten support
Contributor @jerbob92 together with @mathetake brought quite some improvements to our Emscripten support.
- There is now improved support to
longjmp
, especially useful to exception handling (#1611). - We are now allowing a host function to make a nested invocation to another host function (#1626, #1636).
- We are exposing some new experimental APIs (#1637) to support a go implementation of Emscripten's Embind.
What is Embind? In @jerbob92's words:
Embind allows developers to write C++ code and directly interact with that code from Javascript in the browser. It also allows to call Javascript methods directly from C++. [...] [The Wazero implementation] is trying to be a 1-on-1 implementation of the JS version in Emscripten so that the same codebase can be used for both Web and WASI WebAssembly builds.
Embind support lives in its own module and you can check it out at jerbob92/wazero-emscripten-embind!
Go Version Upgrade
As you may already know, we follow the Go support policy: i.e., we support each major Go release until there are two newer major releases: in v1.4.0 we added support to Go 1.21, while keeping support to Go 1.18 for a little while more. The time has come to say goodbye to Go 1.18: it's been an honor and a privilege, sir. 🫡
@evacchi (#1622) and @ncruces (#1620) upgraded the code paths that were relying on old workarounds or simply pointed to an older version.
Other Contributions
-
While working on Emscripten support, @jerbob92 discovered that looking up and calling a non-existing function may SIGILL on some platforms (#1621). Together with @evacchi, they conducted some detective work and realized that the SIGILL was really due to a cross-compilation bug of a humble
nil
dereference panic @mathetake released a workaround (#1623) while the bug is fixed upstream. -
@mathetake updated our CI to align our test suites to their upstream (#1617, #1619, #1650).
-
Some minor issues in path handling were fixed by @evacchi in #1648
-
We also welcome first-time contributor @philippgille who made a fix to our README! (#1629)
v1.4.0
This release is hot 🔥 like a torrid summer sun! 🏖️
Let us all rejoyce: Go 1.21 is out!! We are now promoting the existing CI tests against the Go development branch to tests against the 1.21
stable release (#1616).
As you know may already know, we follow the Go support policy: i.e., we support each major Go release until there are two newer major releases: this means starting with the next release we will drop support for 1.18
!
In case you missed it, WasmCon 2023 is taking place in Bellevue, 5-6 September so if you happen to be there, you might bump into @evacchi, who will be there to deliver a talk on your favorite zero-dependency Wasm runtime for Go (yes, that's wazero).
If you won't be there, don't forget we always hang out in the gophers slack #wazero channel. Note: You may need an invite to join gophers. Regardless, if you like what we are doing, remember to star our repo because that's what the cool kids do 😎
In the meantime, let's take a look at what is new with this release. We have the usual influx of fixes and improvements and a major feature in experimental state: enter the Virtual File System API!
Virtual File System API
Thanks to a final spike before the release @codefromthecrypt, with a lil' help from @evacchi, completed this long-awaited feature, closing issue #1013.
It is now possible to configure a virtual file system using a lower-level API under experimental/sysfs
, experimental/sys
. In order to configure a custom file system you can type:
import(
"github.com/tetratelabs/wazero/experimental/sys"
"github.com/tetratelabs/wazero/experimental/sysfs"
)
...
cfg := wazero.NewModuleConfig().
WithFSConfig(wazero.NewFSConfig().(sysfs.FSConfig).
WithSysFSMount(<experimentalsys.FS>, <guestPath>))
This lower-level API gives a higher degree of control over lower-level FS operations, as compared to fs.FS
, and ensure cross-platform portability. It handles experimentalsys.File
instances (instead fs.File
or os.File
) and returns experimentalsys.Errno
in case of error.
For instance, sysfs.DirFS
is equivalent to os.DirFS
and may be instantiated with:
fs := sysfs.DirFS("/some/path")
AdaptFS
adapts an fs.FS
:
adapted = &sysfs.AdaptFS{FS: fs}
You can also embed most of these types in your struct to provide default behavior to your own implemementation; for instance ReadFS
provides a read-only view over a file system; there is also an experimentalsys.UnimplementedFS
(returning experimentalsys.ENOSYS
for most operations) that should be always embedded in your own implementation for forward compatibility. You can find examples under experimental/sysfs
.
Notably, the Virtual File System implementation does not currently expose methods to override blocking/nonblocking behavior; during this release @evacchi and @codefromthecrypt collaborated on these internals (#1596, #1597, #1599, #1604, #1612, #1613), including the wasip1
poll_oneoff
implementation, which was improved and simplified. Related File
APIs may eventually be exposed to the VFS layer as well.
Cross-Compilation Improvements
It is now possible to build wazero successfully on GOOS=plan9
(@codefromthecrypt #1603), incidentally, this also makes it possible to build on GOOS=js
(@mathetake, #1614) and GOOS=wasip1
: yes we heard you like wazero, so now you can put wazero in your wazero so YOU CAN WASM WHILE YOU WASM.
Other Contributions
-
@panchen66 discovered a memory leak (#1600) happening when repeatedly re-instantiating a module. @ncruces and @achille-roussel tag-teamed (#1608, #1609) a simplified reproducer and a solution. Huge thanks!
-
@anuraaga contributed a fix to the amd64 compiler in case of error, and some doc corrections (#1593, #1593)
-
Other fixes to the documentation
- TinyGo docs (@codefromthecrypt, #1590)
- Updated specs.md with
sock_*
(@evacchi, #1598) - Fixed paths in README.md (sho-hata, #1591)