WebAssembly Procedure Calls

WebAssembly’s current specification only allows for the host to invoke functions (exports) with numeric parameters and accept only a single numeric parameter in return. The same goes for the reverse of that communication–a WebAssembly module can only make host invocations (imports) with numeric parameters and a single numeric return value.

There are a number of ways to get around this. We could use tools and specifications to generate strongly-typed wrappers for each of the modules that we want to host (something like this is planned for the Interface Types proposal). There’s quite a bit of merit to ideas like this.

However, with waPC, WebAssembly Procedure Calls, we wanted the same kind of flexibility that you get with gRPC, where you can pass a formatted string as an operation, some arbitrary payload, and get some arbitrary payload in response.

This is how waPC was born. At its core, waPC is a contract that defines a means for bi-directional communication between guest and host where neither the guest nor the host need know about the other’s memory management strategy.

When we use tools that generate code based on some assumptions about the host runtime (like the ones that work with JavaScript), we generate a tight coupling to the memory management system of the host runtime.

waPC does no such thing and, giving the ability for wasm targets produced by multiple different languages to all easily comply with the contract. For example, we have built sample guests and hosts using Go, AssemblyScript, and Zig, a language that uses explicit memory allocators.