Commit Graph

132 Commits

Author SHA1 Message Date
Crypt Keeper
1e0f88bc14 deps: upgrades to TinyGo v0.28.1 (#1512)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-06-12 14:21:00 +10:00
Crypt Keeper
e31856d360 updates external tool versions (#1498)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-06-02 15:53:29 +08:00
Nuno Cruces
38a7a0f730 examples(allocation): ensure message outlives host call (#1436)
Signed-off-by: Nuno Cruces <ncruces@users.noreply.github.com>
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Co-authored-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-05-05 11:21:13 +02:00
Luca Burgazzoli
b2c11d8dfd examples(allocation): free memory after unmarshalling a result from the guest (#1390)
Signed-off-by: Luca Burgazzoli <lburgazzoli@gmail.com>
2023-05-03 07:01:05 +08:00
Adrian Cole
ab78591915 Revert "examples(allocation): free memory after unmarshalling a result from the guest (#1368)"
This reverts commit 5aafcc4836.
2023-04-18 13:28:44 +02:00
Luca Burgazzoli
5aafcc4836 examples(allocation): free memory after unmarshalling a result from the guest (#1368)
Signed-off-by: Luca Burgazzoli <lburgazzoli@gmail.com>
2023-04-18 07:38:10 +02:00
Takeshi Yoneda
967df4c1ff example: anonymous module in concurrent instantiation (#1338)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-04-03 15:03:20 +09:00
Crypt Keeper
25493fe271 gojs: makes experimental status explicit (#1200)
Before, our README said gojs `GOOS=js compiled wasm` was experimental.
However, as we head to 1.0 we should be more explicit about that.

When we started gojs, there was no likely future where `GOOS=wasi` would
happen in the standard go compiler. This has changed, so we'll only keep
the gojs package around until wasi is usable for two Go releases. Being
in an experimental package helps others know to watch out for this.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-03-06 09:22:58 +08:00
Crypt Keeper
75aa6b2a6e examples: updates to the latest SDKs (#1169)
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>
2023-02-27 09:05:48 +08:00
Crypt Keeper
b758344212 API BREAK: renames InstantiateModuleFromBinary to Instantiate (#1129)
This renames `InstantiateModuleFromBinary` to `Instantiate` to both make
first time use simpler to write and also de-complicate adding a
`WithConfig` variant as requested in #1105

End users in simple case need to change their signature like so.
```diff
-       mod, err := r.InstantiateModuleFromBinary(ctx, addWasm)
+       mod, err := r.Instantiate(ctx, addWasm)
```

In practice, many will not need to change their signature because they
had to use the `InstantiateModule` function in order to assign
configuration such as the module name, filesystem or use a real clock.
Instead, they had to use the more complicated chain of `CompileModule`
and `InstantiateModule` even when only assigning config. Users in this
situation can opt into the more simplified syntax below:

```go
mod, err := r.InstantiateWithConfig(ctx, addWasm,
	wazero.NewModuleConfig().WithName("adder"))
```



```diff
-       mod, err := r.InstantiateModuleFromBinary(ctx, addWasm)
+       mod, err := r.Instantiate(ctx, addWasm)
```

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-02-15 14:52:17 -10:00
Takeshi Yoneda
b68ee641cc ci: update TinyGo to 0.27 (#1120)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-02-13 17:38:53 +09:00
Takeshi Yoneda
addd312dda example: concurrent instantiation per Goroutine (#1107)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2023-02-09 08:34:37 +09:00
Crypt Keeper
f9db80624d zig: bumps to latest (#1080)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2023-01-30 16:30:52 +02:00
Edoardo Vacchi
c324c671d0 docs: add zig section (#1051)
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
2023-01-23 19:54:05 +09:00
Matt Layher
40208a86e2 examples/basic: parse positional arguments with flags (#1028)
Signed-off-by: Matt Layher <mdlayher@gmail.com>
2023-01-14 07:07:26 +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
126bd9050d Removes context parameter from instruction-scoped operations (#923)
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>
2022-12-14 16:08:07 +09:00
Takeshi Yoneda
7221ded05d wasi: adds Zig stdlib test case for (#882)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-12-08 12:28:28 +09:00
Takeshi Yoneda
704f6c9546 example: use the stable Zig 0.10.0 (#854)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-11-16 10:21:20 -08:00
Crypt Keeper
329ccca6b1 Switches from gofmt to gofumpt (#848)
This switches to gofumpt and applies changes, as I've noticed working
in dapr (who uses this) that it finds some things that are annoying,
such as inconsistent block formatting in test tables.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-11-09 05:48:24 +01:00
Crypt Keeper
d108ce4c43 Restores ability to define host functions w/o context via reflection (#832)
This restores the ability to leave out the initial context parameter
when defining functions with reflection. This is important because some
projects are porting from a different library to wazero, and all the
alternatives are not contextualized.

For example, this project is porting envoy host functions, and the
original definitions (in mosn) don't have a context parameter. By being
lenient, they can migrate easier.

See 6b813482b6/pkg/proxywasm/wazero/imports_v1.go

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-10-28 12:44:12 -07:00
Crypt Keeper
be33572289 Adds HostFunctionBuilder to enable high performance host functions (#828)
This PR follows @hafeidejiangyou advice to not only enable end users to
avoid reflection when calling host functions, but also use that approach
ourselves internally. The performance results are staggering and will be
noticable in high performance applications.

Before
```
BenchmarkHostCall/Call
BenchmarkHostCall/Call-16            	 1000000	      1050 ns/op
Benchmark_EnvironGet/environGet
Benchmark_EnvironGet/environGet-16         	  525492	      2224 ns/op
```

Now
```
BenchmarkHostCall/Call
BenchmarkHostCall/Call-16            	14807203	        83.22 ns/op
Benchmark_EnvironGet/environGet
Benchmark_EnvironGet/environGet-16         	  951690	      1054 ns/op
```

To accomplish this, this PR consolidates code around host function
definition and enables a fast path for functions where the user takes
responsibility for defining its WebAssembly mappings. Existing users
will need to change their code a bit, as signatures have changed.

For example, we are now more strict that all host functions require a
context parameter zero. Also, we've replaced
`HostModuleBuilder.ExportFunction` and `ExportFunctions` with a new type
`HostFunctionBuilder` that consolidates the responsibility and the
documentation.

```diff
 ctx := context.Background()
-hello := func() {
+hello := func(context.Context) {
         fmt.Fprintln(stdout, "hello!")
 }
-_, err := r.NewHostModuleBuilder("env").ExportFunction("hello", hello).Instantiate(ctx, r)
+_, err := r.NewHostModuleBuilder("env").
+        NewFunctionBuilder().WithFunc(hello).Export("hello").
+        Instantiate(ctx, r)
```

Power users can now use `HostFunctionBuilder` to define functions that
won't use reflection. There are two choices of interfaces to use
depending on if that function needs access to the calling module or not:
`api.GoFunction` and `api.GoModuleFunction`. Here's an example defining
one.

```go
builder.WithGoFunction(api.GoFunc(func(ctx context.Context, params []uint64) []uint64 {
	x, y := uint32(params[0]), uint32(params[1])
	sum := x + y
	return []uint64{sum}
}, []api.ValueType{api.ValueTypeI32, api.ValueTypeI32}, []api.ValueType{api.ValueTypeI32})
```
As you'll notice and as documented, this approach is more verbose and
not for everyone. If you aren't making a low-level library, you are
likely able to afford the 1us penalty for the convenience of reflection.
However, we are happy to enable this option for foundational libraries
and those with high performance requirements (like ourselves)!

Fixes #825

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-10-28 07:51:08 -07:00
Crypt Keeper
1cbb496c26 Stops using "ex." to abbreviate "for example" (#827)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-10-24 11:51:48 +09:00
Crypt Keeper
761347db1e Replaces MemorySizer and CompileConfig with RuntimeConfig (#815)
We formerly introduced `MemorySizer` as a way to control capacity independently of size. This was the first and only feature in `CompileConfig`. While possibly used privately, `MemorySizer` has never been used in public GitHub code.

These APIs interfere with how we do caching of compiled modules. Notably, they can change the min or max defined in wasm, which invalidates some constants. This has also had a bad experience, forcing everyone to boilerplate`wazero.NewCompileConfig()` despite that API never being used in open source.

This addresses the use cases in a different way, by moving configuration to `RuntimeConfig` instead. This allows us to remove `MemorySizer` and `CompileConfig`, and the problems with them, yet still retaining functionality in case someone uses it.

* `RuntimeConfig.WithMemoryLimitPages(uint32)`: Prevents memory from growing to 4GB (spec limit) per instance.
  * This works regardless of whether the wasm encodes max or not. If there is no max, it becomes effectively this value.
* `RuntimeConfig.WithMemoryCapacityFromMax(bool)`: Prevents reallocations (when growing).
  * Wasm that never sets max will grow from min to the limit above.

Note: Those who want to change their wasm (ex insert a max where there was none), have to do that externally, ex via compiler settings or post-build transformations such as [wabin](https://github.com/tetratelabs/wabin)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-29 08:03:03 +08:00
Anuraag Agrawal
84488768e4 Initial wazero CLI to run a standalone Wasm binary (#813)
* Initial wazero CLI to run a standalone Wasm binary

Signed-off-by: Anuraag Agrawal <anuraaga@gmail.com>
2022-09-28 20:59:38 +09:00
Crypt Keeper
1561c4ca7b Adds MustInstantiate to host imports (#814)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-28 16:21:30 +08:00
Crypt Keeper
429334cf98 Renames ModuleBuilder to HostModuleBuilder and drops memory and globals (#812)
We at one point considered making `ModuleBuilder` create complete
WebAssembly binaries. However, we recently spun out
[wabin](https://github.com/tetratelabs/wabin), which allows this.

Meanwhile, the features in `ModuleBuilder` were confusing and misused.
For example, the only two cases memory was exported on GitHub were done
by accident. This is because host functions act on the guest's memory,
not their own.

Hence, this removes memory and globals from host side definitions, and
renames the type to HostModuleBuilder to clarify this is not ever going
to be used to construct normal Wasm binaries.

Most importantly, this simplifies the API and reduces a lot of code. It
is important to make changes like this, particularly deleting any
experimental things that didn't end up useful.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Co-authored-by: Anuraag Agrawal <anuraaga@gmail.com>
2022-09-28 14:42:14 +08:00
Crypt Keeper
003d41dd5e Updates all 3rd party dependencies (#802)
wazero has no runtime deps. This updates tools we use as well as
dependencies used in comparison with other runtimes.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-07 11:02:26 +08:00
Crypt Keeper
b01effc8a9 Top-levels CoreFeatures and defaults to 2.0 (#800)
While compilers should be conservative when targeting WebAssembly Core
features, runtimes should be lenient as otherwise people need to
constantly turn on all features. Currently, most examples have to turn
on 2.0 features because compilers such as AssemblyScript and TinyGo use
them by default. This matches the policy with the reality, and should
make first time use easier.

This top-levels an internal type as `api.CoreFeatures` and defaults to
2.0 as opposed to 1.0, our previous default. This is less cluttered than
the excess of `WithXXX` methods we had prior to implementing all
planned WebAssembly Core Specification 1.0 features.

Finally, this backfills rationale as flat config types were a distinct
decision even if feature set selection muddied the topic.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-06 15:14:36 +08:00
Crypt Keeper
d54008922c Redirects users to tested example (#791)
Rather than clutter both the README and home page with details that can
drift and have caused maintenance, this directs users to the tested
basic example.

This also adds a FAQ entry about TinyGo's main, thanks to @basvanbeek
for the help.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-09-01 09:12:37 +08:00
Takeshi Yoneda
25b99bc02a example: remove deprecated replace-import example link (#786)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-08-31 14:02:04 +08:00
Crypt Keeper
8abe345249 Elaborates impact of GOWASM variable when compiling Go (#785)
Thanks to @inkeliz for the pointer!

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-31 12:21:34 +08:00
Crypt Keeper
5bd521eb3c Moves host function imports into their own directory (#784)
Our root directory is getting crowded and it is also difficult to
organize the "host imports" concept due to this.

This moves common and language-specific imports into their own
directory. This will break go import signatures on the next release, but
is more sustainable overall.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-31 10:22:15 +08:00
Crypt Keeper
f2b141ef9c Updates to AssemblyScript 0.21 which no longer includes WASI (#776)
This updates to AssemblyScript 0.21 which no longer includes WASI. This
updates guidance to use the shim, which I verified works.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-29 16:55:32 +08:00
Crypt Keeper
3477e61aed Adds gojs for Go generated Wasm (#621)
This adds an experimental package gojs which implements the host side of Wasm compiled by GOARCH=wasm GOOS=js go build -o X.wasm X.go

This includes heavy disclaimers, in part inherited by Go's comments https://github.com/golang/go/blob/go1.19/src/syscall/js/js.go#L10-L11
Due to this many will still use TinyGo instead.

That said, this is frequently asked for and has interesting features including reflection and HTTP client support.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-26 13:43:21 +08:00
Crypt Keeper
c00cb1bd53 site: elaborates concurrency and TinyGo notes; adds Rust notes (#764)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-25 12:02:02 +08:00
Crypt Keeper
6d1d7d33aa site: Adds languages page, starting with TinyGo (#759)
This consolidates common notes we've had into a landing page.
This is intentionally only simplified content for TinyGo to make the
first review easier (as well the writing easier). After this, PRs will
happen to consolidate the other notes we have sporadically in the
examples directory.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-23 15:40:29 +08:00
Crypt Keeper
109c9cb500 Adds 1.0 release plan to README and site (#755)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-19 16:43:15 +08:00
Crypt Keeper
57a705e594 Disallows nil context and fixes linters (#754)
staticcheck linters broke until recent golangci-lint. Now, normal
behaviour of enforcing no nil context works again. Ex.
```
assemblyscript/assemblyscript_example_test.go:16:25: SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
	r := wazero.NewRuntime(nil)
```

Since default lint already checks for nil context, this removes our
permission of nil context args. The original reason we permitted nil is
no longer valid: we once allowed context to be stashed in config, and
removed that as it caused bugs. We forgot to undo allowing nil
explicitly.

Note: this doesn't particularly check in our code for nil context,
similar as we don't particularly check in our code for nil anything
else. End users should use linters as none of our parameters should be
nil anyway.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-19 14:52:50 +08:00
Takeshi Yoneda
076d3245e3 Pass context into NewRuntime (#748)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-08-18 14:47:49 +09:00
Teppei Fukuda
bed4959f6d Adds Zig example (#741)
Signed-off-by: knqyf263 <knqyf263@gmail.com>
2022-08-11 16:31:06 +08:00
Crypt Keeper
fe56fabd63 Removes invalid ignore files (#734)
None of the examples suggest `go build` first anymore.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-08-04 19:57:03 +12:00
Takeshi Yoneda
c50ed2c263 example: adds missing error check (#727)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-30 11:34:33 +09:00
Takeshi Yoneda
02c23d55db Disallow direct call of host functions (#723)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-30 09:33:20 +08:00
Takeshi Yoneda
ed068597cd ci: adds Go 1.19.0-rc.2 into matrix (#714)
This adds the 1.19.0-rc2. in the testing matrix.

This also formats the Godocs across the codebase, as
Go 1.19 has started auto-formatting Godoc. https://github.com/tetratelabs/wazero/issues/426

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-25 11:14:00 +09:00
Crypt Keeper
0d76b11d66 Adds Emscripten integration (#678)
This adds a toehold integration for emscripten users, so they don't
have to define the memory growth function.

Fixes #601

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-18 07:51:48 +08:00
Crypt Keeper
b1f4ced425 Uses Zig 0.10.0-dev for cc, adding the name section (#706)
This manually installs in CI until 0.10.0 is released.

Here's the example wasm trace output from cat.c:
```
--> ._start.command_export()
	--> .__wasm_call_ctors()
		--> .__wasilibc_populate_preopens()
			==> wasi_snapshot_preview1.fd_prestat_get(fd=3,result.prestat=1048568)
			<== ESUCCESS
			--> .dlmalloc(2)
			<-- (1051568)
			==> wasi_snapshot_preview1.fd_prestat_dir_name(fd=3,path=1051568,path_len=1)
			<== ESUCCESS
			--> .dlmalloc(32)
			<-- (1051584)
			--> .memset(32,0,1051584)
			<-- (1051584)
			--> .memcpy(0,0,1051584)
			<-- (1051584)
			--> .free(0)
			<-- ()
			--> .dlmalloc(1)
			<-- (1051632)
			--> .memcpy(1,1051569,1051632)
			<-- (1051632)
			--> .free(1051568)
			<-- ()
			==> wasi_snapshot_preview1.fd_prestat_get(fd=4,result.prestat=1048568)
			<== EBADF
		<-- ()
	<-- ()
	--> ._start()
		--> .__original_main()
			==> wasi_snapshot_preview1.args_sizes_get(result.argc=1048024,result.argv_buf_size=1048028)
			<== ESUCCESS
			--> .dlmalloc(15)
			<-- (1051648)
			--> .dlmalloc(12)
			<-- (1051568)
			--> .memset(12,0,1051568)
			<-- (1051568)
			==> wasi_snapshot_preview1.args_get(argv=1051568,argv_buf=1051648)
			<== ESUCCESS
			==> wasi_snapshot_preview1.fd_fdstat_get(fd=3,result.stat=1048544)
			<== ESUCCESS
			==> wasi_snapshot_preview1.path_open(fd=3,dirflags=1,path=1051654,path_len=8,oflags=0,fs_rights_base=0,fs_rights_inheriting=0,fdflags=0,result.opened_fd=1048572)
			<== ESUCCESS
			==> wasi_snapshot_preview1.fd_read(fd=4,iovs=1048544,iovs_len=1,result.size=1048572)
			<== ESUCCESS
			==> wasi_snapshot_preview1.fd_write(fd=1,iovs=1048544,iovs_len=1,result.size=1048572)
greet filesystem
			<== ESUCCESS
			==> wasi_snapshot_preview1.fd_read(fd=4,iovs=1048544,iovs_len=1,result.size=1048572)
			<== ESUCCESS
			==> wasi_snapshot_preview1.fd_close(fd=4)
			<== ESUCCESS
		<-- (0)
	<-- ()
	--> .__wasm_call_dtors()
		--> .__stdio_exit()
		<-- ()
	<-- ()
<-- ()

```

Special thanks to @Luukdegram for supporting the `--export` linker
argument even if this particular example doesn't use it.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-16 15:53:53 +08:00
Crypt Keeper
14d892d310 Removes api.ImportRenamer for a different approach to "env" (#680)
Before, we introduced a type `api.ImportRenamer` to resolve conflicts
where the "env" module was shared between AssemblyScript and
user-defined functions. This API was never used in GitHub, and is
complicated.

AssemblyScript also isn't the only ABI to share the "env" module, as
other web APIs like Emscripten do also. The less complicated approach is
to have packages that need to share "env" use
`ModuleBuilder.ExportFunctions` instead, and use namespaces as needed if
there is overlap.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-11 14:57:26 +08:00
Takeshi Yoneda
09a8aa6030 example(wasi): fixes link drifts (#679)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2022-07-11 07:33:41 +08:00
Crypt Keeper
f0e05fb95b examples: adds rust build and WASI example (#676)
This fixes where our pull requests didn't check the rust source in
examples were valid. It also adds an example of wasi with rust.

This uses cargo-wasi because the default target creates almost 2MB of
wasm for a simple cat program.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
2022-07-08 10:49:50 +08:00