
WebAssembly Interface Types: Interoperate with All the Things - skellertor
https://hacks.mozilla.org/2019/08/webassembly-interface-types/
======
the_duke
I'm very happy to see the WebIDL proposal replaced with something generalized.

The article brings up an interesting point:

Webassembly really could enable seamless cross-language integration in the
future.

Writing a project in Rust, but really want to use that popular face detector
written in Python?

And maybe the niche language tokenizer written in PHP?

And sprinkle ffmpeg on top, without the hassle of target-compatible
compilation and worrying about use after free vulnerabilities?

No problem use one of the many WASM runtimes popping up (like [1], [2]) and
combine all those libraries by using their pre-compiled WASM packages
distributed on a package repo like WAPM [2], with auto-generated bindings that
provide a decent API from your host language.

Sounds too good to be true? Probably, and there are plenty of issues to solve.

But it sounds like a future where we could prevent a lot of the re-writes and
duplication across the open source world by just tapping into the ecosystems
of other languages.

[1] [https://wapm.io/](https://wapm.io/) [2]
[https://github.com/CraneStation/wasmtime](https://github.com/CraneStation/wasmtime)
[2] [https://wapm.io/](https://wapm.io/)

~~~
wahern
JVM (Java), Parrot (Perl 6 VM) and CLR (C#) shipped easy, multi-language
environments over a decade ago. For some definitions of "easy" and "multi-
language".

Different programming languages exist for many reasons, only one of which is
syntax. Many of these reasons relate to data structures and runtime control
flow. WASM won't be able to "solve" these issue any better than the JVM,
Parrot, or CLR did. (Spoiler: they didn't, and WASM won't.) At best you'll get
a Rust'ish WASM, Python'ish WASM, PHP'ish WASM, etc. And all of those will
feel like a cousin to JavaScript, just as anything on the JVM feels similar to
Java, on Parrot feels similar to Perl 6, and on the CLR feels similar to C#.
WASM's choice of data structures, control flow, and data representations will
be strongly influenced by the requirements of the major JavaScript engines (in
Firefox, Chrome, and maybe WebKit). This is _already_ the case when it comes
to control flow semantics.

~~~
asdkhadsj
Ah, there it is, the JVM discussion in any WASM thread. I kid.

On topic though, I'll be curious to see how bad it really is. The demo video
showed code that ended up looking and behaving like normal Rust code. Maybe
you'll end up with some oddities like Rust enums not being supported, but w/e.

At the end of the day, I don't need to make weird and often gross C bindings
in my Rust or Go code. Is that not a huge win?

But you're right, maybe this will go the way of the JVM and no one will care.
Or maybe not. Does it matter?

 _edit_ : And I should add, maybe I keep forgetting where my well supported
JVM Python <-> Rust or Go <-> Rust bridge is. Maybe someone can remind me,
because I've not seen it.

~~~
ori_b
> _At the end of the day, I don 't need to make weird and often gross C
> bindings in my Rust or Go code. Is that not a huge win?_

You just need to manually insert stack growth checks before all function calls
in anything that can be called from go to support goroutines, because those
can't live on a normal stack and still be sufficiently small to support
desired go semantics. Async has similar issues, where the semantics are
incompatible, which means that many things go horribly wrong in cross-language
calls

Or you use a lowest common denominator and essentially treat the thing like an
rpc, with a thick layer to paper over semantic mismatches.

And that's before we get to things like C++ or D templates, Rust or Lisp
macros, and similar. Those are lazy syntactic transformations on source code,
and are meaningless across languages. Not to mention that, if unused, they
produce no data to import. But, especially in modern C++, they're incredibly
important.

~~~
afiori
I think Rust macros and C++ templates are not lazy wrt execution.

~~~
ori_b
They are lazy wrt compilation. So, unless you use the specialization in C++ or
Rust, there's no code to call.

    
    
        std::vector<Java.lang.Object> 
    

Simply doesn't exist for interop code to call.

------
syrusakbary
Super happy to see WebAssembly Interface Types in development!

At Wasmer (disclaimer, I'm the founder!) we've been creating integrations with
a lot different languages (C, C++, Rust, Python, Ruby, PHP, C# and R) and we
agree that this is a pain point and an important problem to solve. We're
excited that Mozilla is also pushing this forward.

If you want to start using WebAssembly anywhere:
[https://wasmer.io/](https://wasmer.io/)

Keep up the good work! Let's bring WebAssembly everywhere!

~~~
jedisct1
Is this going to replace wasmer's WebAssembly interfaces?

As a library implementer, I'm a bit lost about how to expose functions from a
wasm module to the outside world.

wasmer's interfaces have the advantage of being very simple to write. But they
are not very expressive.

WebIDL is horrible, albeit more expressive.

At the same time, I feel like this is not enough.

My experience with libsodium.js, one of the first library exposing wasm (and
previously asm.js) to other environments, has been that IDLs simply exposing
function interfaces are not good enough.

For example, C functions returning 0 or -1 to indicate an error or not, would
not be idiomatic at all if exposed that way in Scala, Javascript or Python. We
want these to raise an exception instead.

Also, we need ways to preallocate buffers, check their size, etc. in order to
make things appear more idiomatic.

In libsodium.js, the description language for the WebAssembly <-> JS glue is
JSON-based. It describes the input and output types, but also their
constraints, and how to interpret the output. That was necessary, and if more
languages are targeted, this is even more necessary.

I feel like WebIDL is both complex, and insufficient.

Another thing that I don't necessarily get is why such a description language
was designed specifically for WebAssembly.

Instead, we could have (yet another) way to describe APIs and how to encode
that description. That description can then be included in ELF libraries, in
Java objects, in WebAssembly modules, whatever. You know, like, what debuggers
already use.

------
adev_
Side comment: a Thumbs-up for Lin Clark and her usual Mozilla blog posts
including this one.

It is easy to understand, very informative and the hand-drawn infographies
makes it pleasant to read.

~~~
CraftThatBlock
Would also like to add that the video in the article
([https://www.youtube.com/watch?v=Qn_4F3foB3Q](https://www.youtube.com/watch?v=Qn_4F3foB3Q))
is really well made and to the point

------
sunfish
Note that Wasmtime is the engine starring in the blog post and demos :-).

Of course, cross-language interfaces will always have tradeoffs. But we see
Interface Types extending the space where the tradeoffs are worthwhile,
especially in combination with wasm's sandboxing.

------
duxup
I'm gonna go out on a limb here and expose my n00bishness, and honestly a lot
of that article has my head spinning as I google a lot of terms ;)

I've only done web development for a year now and I've seen some cool
WebAssembly demos but mostly those are demos of various frameworks (or no
framework) reusing random WebAssembly components.

It's cool, but I'm missing from a large web application stance how WebAssembly
is supposed to work, specifically when it comes to stuff like you see in some
frameworks with state management across components and etc. Is there an
example of that?

~~~
vcarl
Web assembly is generally an optimization, not an app alternative. Think of it
the way you would the C bindings Node.js has. If you've got a compute-heavy
code path, writing it in C (or Rust etc) and shipping it as web assembly could
be a dramatic perf improvement, but there's not really a substantive benefit
to writing your entire app with it.

~~~
asdkhadsj
> but there's not really a substantive benefit to writing your entire app with
> it.

Amendment: Perhaps it's debatable what "substantive benefit" would be, but
writing the whole app in it is a huge benefit if you really want to do that.
That is to say, for years people wanted to write Web UI stuff in various
languages, this also allows for that.

So while the concrete performance boost may not be meaningful in writing an
entire web app in C, Rust, Go, Python or w/e - to the developer happiness the
boost may be huge for those devs that want it.

~~~
vcarl
Well, you still can't do that—WASM doesn't have DOM bindings, you'd still have
to ship out to JS. I believe that's a goal, so yes eventually that could be a
benefit, but not at the moment.

~~~
pjmlp
DOM bindings are kind of irrelevant when one has WebGL.

One example among many ramping up

[https://platform.uno/](https://platform.uno/)

~~~
mrec
For a smallish subset of use cases, maybe. But replacing the DOM with a
canvas-based UI for general use would be reinventing many of the problems of
Flash.

~~~
pjmlp
Many designers and game devs see it otherwise.

~~~
TeMPOraL
Gamedev is a separate topic. As for designers, they are on the opposite side
from users in the tug-of-war of control over content rendering. I don't
believe they should get 100% of their way.

~~~
mrec
Gamedev falls squarely into my "smallish subset of use cases". It does
legitimately need non-DOM UI, but it's not a huge part of the Web (yet).

As for designers, thank you for finding a much more diplomatic phrasing than
the one I was about to write.

------
mkl
> Document.createElement() takes a string. But when I call it, I’m going to
> pass you two integers. Use these to create a DOMString from data in my
> linear memory. Use the first integer as the starting address of the string
> and the second as the length.

This seems like its introducing buffer overflow vulnerabilities, if the code
can be tricked into using the wrong numbers. Sure, just into WebAssembly
memory, but if everything's implemented in WebAssembly, won't there often be
sensitive information in there?

Doing some more research, it seems like this may be a common problem:
[https://stackoverflow.com/questions/41353389/how-can-i-
retur...](https://stackoverflow.com/questions/41353389/how-can-i-return-a-
javascript-string-from-a-webassembly-function)

~~~
CUViper
Doesn't each wasm module get its own isolated memory? If so, then you could
only shoot your own sensitive foot.

~~~
kevingadd
Yes, but a "module" can be an application and a full set of its dependencies.
It's unlikely that its dependencies would have isolated heaps, as there would
be no way for them to communicate (they can't touch each others' pointers,
etc) other than through intermediary JS.

So any vulnerability in any piece of wasm in your webpage effectively
compromises everything. One compromised module can also likely reach out into
the page and then use other modules' public interfaces to compromise them too.
There is not sandboxing in place to prevent this sort of attack, the sandbox
merely protects the browser from attack by content.

------
lachlan-sneff
So this is what they've been up to!

How well will this interact with the upcoming (hopefully before the heatdeath
of the universe) rich gc types extension?

~~~
sunfish
Interface types will make it easy for two modules to interface with each
other, regardless of whether both sides use GC, just one side does, or neither
side does. And even within GC types, different languages have different ways
of representing strings, and Interface Types can allow them to talk to each
other.

------
aloknnikhil
Good effort. But the bit about using Protobuf, Cap'nProto only in processes
that don't share memory is wrong. Sure, that may not be how they're
traditionally used. But that doesn't exclude me from defining opaque C FFIs
that pass/return opaque bytes that are serialized messages and have it be
deserialized on the other end.

------
hackcasual
Glad to see this being worked on. The difference between a heap vs. runtime
managed object is a huge perf gap for tightly interoperating JS and WASM. At
my company, we built a specific object representation that would allow zero
copy, through array buffer sharing, views of C++ data from Javascript. Sounds
very similar to this.

~~~
ptx
I got the impression from the article that it will always copy data (e.g.
strings) between wasm modules. Did I misread it?

------
hinkley
I hope someone with their hand in these specs experienced the dumpster fire
that was SOAP interoperability and is taking pains to be sure we don't have
the same class of problems in wasm.

------
gyre007
Oh, this is wonderful. Getting closer to that multilang WASM world.

------
skrowl
WOW that was too much to read. Can someone TLDR when we'll be able to get rid
of Electron using this for me?

~~~
sunfish
Much of what makes Electron Electron are the APIs it provides. The blog post
here is a way to describe and work with APIs, not actual new APIs.

We're working on APIs too, in WASI, but there's a lot of work to do to build
everything you'd need to build Electron-like apps.

------
baybal2
I'm a strong opponent of WASM because I think that WASM will break the
internet the very same way _and same reason_ ActiveX and Java applets broke it
over 20 years ago.

An untrusted executable code, no matter how much sandboxed, virtualised, and
isolated it is, would never be a good thing. It wasn't 20 years ago, and would
never be, invariably of what "tech sauce" it is served with.

I advocate for proactive removal of WASM lobbyists from standard setting
bodies, and countering their promotion of WASM.

~~~
omn1
ActiveX and Java applets were proprietary when they got introduced. WASM is an
open standard that it supported by all browser vendors and already integrated
without any third-party plugins. There is a spec for it that you can
contribute to.

~~~
baybal2
It doesn't change a thing. Both ax and java were quite well documented and
free for everybody to use, but they definitely _broke the Internet_ for
everybody without any exaggeration.

I'll explain you why in the most neutral tone I can.

Do you understand that biggest peddlers of inscrutinable executable format on
the web are people who are _not fine_ with the open nature of the Internet,
and who _can not_ make their business when all code available through the
browser is available to at least minimal form of inspection?

In other words, the people who are mad because they can't run business in the
web because their business model depends on their code being closed, they WANT
THIS big time. Their business thrives off non-interoperability and brokennes
of software at large. Their success comes at the detriment of the Internet
ecosystem at large. The more they brake the Internet for the rest of its
users, the more money they can make, and this is why there can not be
reconciliation with them and, us, the wider and more sane part of software
developer community.

And we, the engineering cadres, the most influential class of people in the
new tech driven world, have all the influence needed to deny WASM adoption.

~~~
AlexanderDhoore
Modern minified javascript is just as inscrutable as anything else.

For example, please try to read this code:
[https://apis.google.com/js/client.js](https://apis.google.com/js/client.js)

You would need a "decompiler" to make anything out of that.

