Does anyone here have experience embedding WebAsse...
# thinking-together
a
Does anyone here have experience embedding WebAssembly VMs? I’d like to talk about where there’s any firm ground from which to start on a FoC idea. I can only find half-finished projects and systems that used to work.
m
have you seen wasmer? https://wasmer.io/
d
I want to create a web assembly compiler and runtime for my language (so I can embed an entire IDE in a web page). Last time I looked, it seemed that WASM was a half-completed work in progress, and the tooling wasn't complete. So the longer you wait, the easier it will be. I figured the sweet spot will be 2021 for my purposes, otherwise I'd be working around limitations and constantly running to catch up. WASM seems to be progressing quickly, so for projects with fewer requirements than mine, it may be ready right now. Issues I noticed, last time I checked, included lack of support for C++ exceptions, threads, vectorized instructions, GPU access, and difficulty of using the C++ build tools. Rust appeared to have the best tooling.
a
It looks like the Vector’s WASM support is still only a proposal(?), and they don’t intend to support my primary OS :-/
Wasmer looks very promising! Thank you!
@Doug Moen If you’re targeting browsers, Rust and Go have decent preliminary support. I’m doing the opposite, wanting to run WebAssembly outside the browser. It looks like Wasmer does that. I’ll dig deeper when I’m at my laptop.
d
@alltom Yeah, I know about Rust. But I'm using C++, and I have large C++ library dependencies. I would only expect Rust to be better if I am compiling pure Rust code. Which isn't an option: those C++ libraries are written by specialists, and some have no Rust equivalents. Compiling a mix of C++ and Rust to WASM is not going to be easier than compiling pure C++ to WASM, I'm pretty sure. It would be an easier choice if the Rust library ecosystem were more mature.
1
s
@alltom if you want to embed and are interested in the security properties of WASM especially, I highly recommend Lucet
@Doug Moen If you have all the source code and it's all in C++ (no inline assembly, etc) then emscripten should be able to handle compiling to WASM+JS shim for web or nodejs or deno
a
I wish I could, but that’s what Vector uses and that RFC says it’s Linux-only. I honestly don’t care if it’s built out of Fisher Price blocks if it works, I’m just prototyping. 😆 Have you used Lucet?
s
Yes. Lucet is great. It runs on MacOS also, though their MacOS support is beta/best effort so not for production use
a
Interesting! Worth a look for me, then, thanks!
s
I was on the team building a Lucet-based WASM serverless system at $DAYJOB
it's not live yet, but very promising generally, especially if security features interest you
a
They do long term, if I get there. :)
e
web assembly is intentionally brain damaged. At present, it is limited to running in a separate thread, and cannot access the DOM directly. All of us JS-haters were hoping for a clean virtual machine with direct API access to the BIOS which would be the DOM. If they had done that it would have created a virtual OS that would have permitted all the languages to easily move to that new universal OS. Instead, JS still rules, and WebAsm is for async heavy computation. Sure you can implement some complex back-and-forth system, but that defeats the whole purpose of getting closer to the metal. If Google & co. let other languages in, it could well lessen their control of the ecosystem. At present the V8 engine reigns supreme; it is an exceptional performing piece of code, but also super complex.
a
I write Go that accesses the DOM all the time and haven’t noticed any indirection. What do you mean?
e
My understanding is that all WASM modules are running in a separate thread and are not able to directly call the "operating system" which includes the event and screen model. And you have to used shared memory blocks to communicate between these two processes. That is not what i call a full opening to other languages in the browser universe. On a mac or pc, or mobile device you can write in any language, and as long as you package it as an executable for the OS, the OS doesn't care a bit which source languages you used.
a
It depends on what’s in the shim. In one sense, you’re right that Go can’t directly call the OS because it only has access to thunks and data that the VM owner puts in its environment, but on the other hand, the OS is accessed in JavaScript entirely through the global object so the “opening” doesn’t need to be very wide at all for access to the OS to be about even in JS and wasm in practice. There must be synchronization overhead if the wasm executes in another thread (I didn’t know it did, that’s good to know!), but I haven’t noticed it. Wasm must be implemented in a more efficient way than Web Workers, because worker isolation is so strict that you can’t call one synchronously from, say, an event handler that needs to finish in one JS event loop tick, but you can call wasm in an event handler. The people working on WASI are trying to create a shim that encompasses every functionality that you’d typically get from an OS, so that every compiler can just target that one shim instead of inventing a new one for their language. That’ll provide some of the language-independence you’re talking about, especially since if it becomes standard, browsers can implement DOM access directly instead of relying on memory sharing with JS. If you’re curious, the Go shim is here, just a few hundred lines: https://github.com/golang/go/blob/master/misc/wasm/wasm_exec.js The system calls it exports to wasm binaries are in importObject (syscall/js.valueGet, syscall/js.valueSet, etc).
f
@alltom I'm currently prototyping a desktop program written in Rust in which I'm using wasm-compiled Rust code as sandboxed plugins. My impression is that wasm is still under heavy development and important proposals like wasm interface types aren't there yet. For my pretty simple use case, I was able to use wasmtime [1]. Due to the lack of interface types, the interaction between VM and wasm code is painfully low-level, but it can be done. What's your use case and which PL would you like to embed the Wasm VM into? [1] https://github.com/bytecodealliance/wasmtime
💡 1
s
I think it's easier to understand WASM if you forget about the "web" part and just see it as a lightweight re-imagining of JVM/.NET without all the built-in garbage collector, OOP system, heavy runtime gunk and just the basics you need to run C (from whence you can run mostly anything)
1
the fact that you can also easily export any functions you want from your host into the WASM space to enable easy interop (at the C level of ints, floats, and pointers) to call any function in the place the WASM is embedded is very nice -- it enables restricting the code's view of the outside world to whatever you want it to have
w
@alltom and others: I work on Wasm tooling (LLVM) at Google, so let me know if you have any specific questions
😮 1
most Wasm VMs that are mature and fast are also large complex beasts, so integration isn't easy.. though that is something we're working on making easier (in V8)
😮 1
there are interepreter options that would be easier to integrate, but Wasm really takes a huge performance hit when interpreted
@Edward de Jong / Beads Project Wasm runs on the same thread as JS, and can interleave calls and integrate tightly with JS
💡 1
What you see as "braindead" is actually Wasms greatest feature: secure by design. it has NO API surface, thus can actually pretty easily be shown to be secure, unlike other VMs (like e.g. the JVM) that can never be fully declared secure because of its endless API surface
that currently means to access the DOM you need to go thru JS, but more direct access (thru "interface types") is coming, all while keeping that rock solid sandbox you think is braindead
and yes, it is intended to let all languages play
a
What stack would you start with if you suspected that interpretation overhead wouldn't be overwhelming?
w
contrary to your belief, the DOM is not the only thing you might want to access.. for example apps built on top of OpenGL port pretty nicely to Wasm already thru emscripten
and of course it was intended to run outside the browser, in any environment
@alltom if you were ok with an interpreter, I would either integrate the one in WABT https://github.com/WebAssembly/wabt which I would have the most faith in being "correct" w.r.t. the spec. but is definitely not fast, or wasm3 https://github.com/wasm3/wasm3 which seems to be the current king of speed in interpreterland
🙏🏼 1
👍 1
what is the language you're integrating into?
In general, it helps to see Wasm as a "secure virtual CPU", not as a "batteries included VM" like JVM or even JS. I guess that is where a lot of confusion comes from.
💯 1
a
@Wouter Go, ideally, but I'm flexible because I just want to prototype. 🙂
w
well there's https://github.com/go-interpreter/wagon, but hard to tell how robust it is.. when evaluating runtimes, you generally want to check how many of the "spec tests" it is able to pass.
is it easy to link in C/C++ libs in Go?
Wasmtime seems a pretty well designed runtime that is also fast, if Rust is an option
a
I’m not dead set against learning Rust. 😅 C is pretty easy to use in Go. Wagon is one of the ones that felt half-finished. I have a test program that just tries to initialize and invoke various wasm VMs in Go and the lack of documentation / examples tripped me up in every single one.
I haven’t tried a few of your recommendations, so I’ll give those a shot!
👍 1