Hacker News new | ask | show | jobs
by comex 1299 days ago
> But with wasm, you just pull in csharp.wasm, python.wasm and java.wasm, so it's just one binding layer, not three.

A bit of a rant, but there's nothing specific to WebAssembly about this.

Whether you're using WebAssembly or native code:

- The basic interface you get between caller and callee is a low-level calling convention, where essentially all you have are integers (which can be pointers), and any higher-level data structures need to be built out of that.

- A slightly higher-level interface is the C ABI; many languages support exporting and consuming APIs using the C ABI, but it can be frustratingly low-level.

- To provide an even higher-level interface, there are bindings generators, which could in principle either be designed as direct language-to-language bridges, or as a single common standard that any language can provide and consume APIs for.

The WebAssembly Component Model standard and the wit-bindgen tool are an example of the latter. They happen to be defined specifically for WebAssembly rather than generically for any architecture. If they become ubiquitous at some point in the future like they're supposed to, then WebAssembly will have an advantage when it comes to high-level bindings, not because of any fundamental technical aspect of WebAssembly itself, but just because people building these bindings on top of WebAssembly have more motivation and more consensus. (WebAssembly does have a technical advantage when it comes to sandboxing between components, but this is relatively unimportant for most use cases.)

But for now, wit-bindgen isn't ubiquitous, and most of those languages don't even work in WebAssembly yet…

2 comments

I work on wit-bindgen. One major advantage of the WebAssembly VM is that we can trust the call stack, which gives cross-language calls optimization opportunities to skip serializarion or copies. This will be an even more important when we add async to the component model, and e.g. async rust can await on async typescript, all in the same “executor” in Rust terms.

Sandboxing also goes a long way towards containing the supply chain security issues that every language is susceptible to.

What do you mean by ‘trust the call stack’? Do you mean trusting that a function you call won’t longjmp out or otherwise break out of the call without returning? (Plenty of native code already assumes that functions it calls won’t do that.) Or something else?
Wasm doesn’t yet have any sort of longjmp instructions. Stack switching is currently a proposal and the leading candidate is based on delimited continuations. Additionally, there are no wasm instructions that can manipulate the control stack besides call, indirect call, and return, which are always typechecked. So, if you call untrusted code, you can be assured that it will not be able to manipulate your stack and that it will either return or trap.

Native code might assume that code it calls won’t misbehave in these ways, but wasm guarantees it, and that allows wasm VMs which run untrusted code to have more efficient implementations.

> A slightly higher-level interface is the C ABI;

Small remark: There is nothing like "the C ABI".

https://faultlore.com/blah/c-isnt-a-language/#c-doesnt-actua...