WebAssembly and Elixir

With WebAssembly just getting started do you guys think that one day we’ll be able to run Elixir in the web browser and use it to do similar tasks that Javascript does today?

2 Likes

There’s no BEAM on any web browser … web assembly or not. So what’s the point?

Sequential programming without the concurrency goodies doesn’t make for a compelling use case.

6 Likes

It’d be entirely possible to make a backend for the compiler (like HiPE is for example) that compiles to webassembly.

Do note, webassembly is NOT just for running in the browser, it is a standard that defines a base bytecode for sandboxed execution. There are webassembly runners in C, Java, even an FPGA washing machine (yes really), none of which have Javascript or any of Javascript’s calls or libraries. It is just another backend, like x86 or ARM.

11 Likes

Whooooa!! Very good idea! Do you think it would be hard to write a new browser on top of BEAM? And of course, support to execute any BEAM code? Is there a BEAM-JS for backward-compatibility? So many ideas coming on! That would be heaven!

5 Likes

Looks like there is a start on it called ErlyJS. But it feels abandoned. Here is a post about it and here is a fork of the original project, which is not available on Google Code anymore.

2 Likes

Thanks for letting me know that. So once it’s fully ready you’d be able to securely isolate Elixir code from the operating system? That sounds really useful :slight_smile:

Technically you could compile the BEAM VM to it now (though single-core mode), probably just need to fill in a few (many) wrapper functions as necessary for ‘OS’ interactions and/or faking. :slight_smile:

2 Likes

I just listened to episode 323 of the Software Engineering Radio podcast today and was struck by similar thoughts. They broached the topic of concurrency issues with WebAssembly and how shared-memory (:scream:) multi-threading (which relies on SharedArrayBuffer) was incapacitated due to unforeseen security issues (SharedArrayBuffer and timing attacks, “Meltdown and Spectre”).

At that point, BEAM dinged in my head.

Either having a web browser built in top of the BEAM or having modern browsers use BEAM as a virtual machine in which to execute WebAssembly or something similar to that. In the extreme, maybe BEAM byte-code could even be a viable alternative to WebAssembly.

Perhaps having Elixir compile to WebAssembly would be interesting. As I understand it, one must use C++ or Rust for that right now (and Go is also adding support for it). WebAssembly has some issues with garbage collection (or, rather, lack thereof) which might make that difficult.

2 Likes

Wow. @DockYard is thinking of investing time to explore compiling @elixirlang and the BEAM to #wasm. Very ambitious and exciting. #ElixirConf

— David Bernheisel (@bernheisel) September 6, 2018

Looks like Dockyard is considering investing in this idea.

7 Likes

Is there any news on weather or not Dockyard is still working in compiling the BEAM to WASM?
(or other organizations or people working on a similar project)

There’s at least:

And elixirscript can run Elixir in JavaScript, and might run in Wasm later on

Seems AtomVM can run erlang in Wasm

5 Likes

That’s really cool! Have you tested it?

There is Enigma VM as well. It might support WebAssembly in the future https://github.com/archseer/enigma

3 Likes

I haven’t tested it yet, but looks very interesting. I was looking into running multi-core logic in the browser recently, and have the emscripten pthreads examples working fine, but it requires allowing shared-array-buffer, which kind of opens up spectre / all the speculation bugs, perhaps a bit more than necessary (and it’s only available behind flags atm).

I was thinking perhaps someone would’ve used BEAM with message passing between Web Workers rather than shared memory, to get scalability without opening up bugs in the hardware architecture. But seems this hasn’t really caught on properly yet.

There was discussion about a rust rewrite in 2017 https://groups.google.com/forum/#!topic/erlang-programming/_LUC8XbsIv4
i’m happy someone is working on it at least :slight_smile:

Being thread-based, Web Workers are heavyweight (compared to BEAM processes) and data transfer between them isn’t particularly fast (thread hop delay 1- 15ms) - which likely explains the focus on SharedArrayBuffer.

Edit: It seems threads for WebAssembly start web workers without the overhead of 4MB for each V8 isolate for JS and share wasm modules.

Google seems to be working on developing a web standard scheduler/task processor for browsers.

See further:

So I suspect that adapting the BEAM scheduler for the browser environment is a non-trivial port and one has to wonder whether the resulting size of the WebAssembly asset may constrain its usefulness.

You need to implement a fault-tolerant, scalable, soft real-time system with requirements for high availability.

… and while concurrency is an obvious goal on the browser, I don’t think anybody is giving fault tolerant or high availability much thought or value.


For the time being WebAssembly for the browser seems to have a role that is similar to NIFs for the BEAM. So it makes sense that C, C++, and Rust are the officially supported languages, while everything else is considered (highly) experimental.

Making the browser do things, scripting the browser via the various browser APIs, is still the domain of ECMAScript.

Web Assembly Concepts:

  1. By itself, WebAssembly cannot currently directly access the DOM; it can only call JavaScript, passing in integer and floating point primitive data types. Thus, to access any Web API, WebAssembly needs to call out to JavaScript, which then makes the Web API call. Emscripten therefore creates the HTML and JavaScript glue code needed to achieve this.

(There are future plans to allow WebAssembly to call Web APIs directly).

3 Likes

Thanks for the links! I was also thinking of the possibility of message passing between workers more like sending messages over the network, and running beam processes inside each worker. Fault tolerance and ability to update code in runtime are interesting for some use cases I have in mind at least. And I have at least one p2p experiment I’d like to try where high-availability would be useful as well.
Rust has relatively good bindings to almost all the apis exposed by browsers now: https://rustwasm.github.io/wasm-bindgen/api/web_sys/
While things like RTCQuicTransport are obviously missing, but that can be worked around anyway, as there’s the escape hatch of calling into js and having access to all the apis from there.
At least for the kinds of experiments I’m thinking of, the size of the assets for the vm wouldn’t matter too much, as those would be updated relatively rarely and could be cached quite well.

1 Like

What about running wasm modules on the beam? I think that would be useful for portability of code. For instance, it would be great if I could get the fault-tolerance guarantees of the BEAM by running a containerized version of something in the beam itself (something like SQLite for example).

1 Like

When I was at CodeBEAM SF, I learned there was a group of people (not sure who), who were looking at porting the BEAM to Rust, so they could take advantage of Rust’s ability to compile to WASM. However, it sounded like it was in very early stages and there were some complexities in how the BEAM made some dynamic calls (if I remember correctly). I wouldn’t be surprised if it’s a couple years before it sees the light of day if ever.

I don’t know that it’s impossible, but I feel like it wouldn’t be very performant. I don’t think the BEAM is optimized to perform the types of operations that are necessary to run WASM code.