WebAssembly
developer.mozilla.org
developer.mozilla.org
You can find the link to the source of any article at the bottom of the page.
Sure, generating HTML via another language is not new, but SSG pushed back against the notion of using dynamic CMS systems (which were de rigueur in the early 2000’s) in favour of static pages hosted on serverless systems and like GitHub pages and S3, with content (mostly markdown) held in version control systems instead of a database.
Beware the lure of MDX/equivalents. If you want to provide structure to your content and maintain it colocated to where you use it (or imported and type checked for where you have that kind of reusability), components in Markdown is an awful experience. Inverting that and writing Markdown within posts is my current solution. It’s not as nice as a plain .md file but it lets me mix writing and structure without compromise
I made a couple of short explainer videos on it:
- design goals and instruction set:https://youtu.be/VOaSaShAYb0
- mechanizing safety proofs for wasm: https://youtu.be/zsPVbmEPTlA
“...provides access to several operating-system-like features, including files and filesystems, Berkeley sockets, clocks, and random numbers, that we'll be proposing for standardization.
It's designed to be independent of browsers, so it doesn't depend on Web APIs or JS, and isn't limited by the need to be compatible with JS.”
"Usenix Security '20-Everything Old Is New Again: Binary Security of WebAssembly"
> Notably, they don't appear to even try to break the WA-host memory barrier, which I actually find to be a validation of the core design goal of WebAssembly: isolate the damage a vulnerable program can inflict to the memory space (and thus also output) of that program. Protect the host from the program, but not the program from itself. Also, maybe don't dump WA output you can't validate directly into DOM.
> Protect the host from the program, but not the program from itself.
All nice and dandy, except that the goal of WebAssembly is to extend the host, and have the host be dependant on the program behaviour.
A host unaware that the program is compromised can be led to take decisions that it wouldn't otherwise do, like allow a basic user to acquire admin credentials, that were supposedly correctly validated by the program.
I am really eager to see the amount of CVE's on WebAssembly to start poping up, then the whole WebAssembly advocates can tell the world why we had to ditch PNaCL and CrossBridge, 10 years of regress, and get the same outcome in the end.
You could say that this is the most web-specific aspect of Web Assebly
If not, then it was just smoke and mirrors to sell an agenda and delay progress 10 years.
"Unreal Engine 3 Support for Adobe Flash Player - Epic Citadel" -> 2011
Regarding the "Everything Old Is New Again: Binary Security of WebAssembly" they find that compiling something like photoshop to a single wasm module forfeits many security features available in x86, but this also point toward a future where application can be compiled in dozens or more small isolated modules. It remains to be seen if this will suceed or fail...
WebAssembly is what the browsers now offer us, so I have to accept it, that doesn't mean I buy into the security story, specially when basic stuff like bounds checking inside the same linear memory segment is not considered as relevant.
That paper is just the first of many yet to come.
On another side, compiling existing C/C++ libraries to wasm is still very painful. I struggled a lot using Emscripten to port FFmpeg to wasm - you have to compile EVERY dependency to wasm (so I ended up re-compiling libopus, libmp3lame, etc.) and the compiler warnings are often super cryptic which made the entire process a complete nightmare. The process really needs a lot of work still.
For anyone that's interested, this is the result from my endeavor: https://github.com/aeroheim/audio-file-decoder
And also check out a great general purpose FFmpeg wasm port here: https://github.com/Kagami/ffmpeg.js
This is a scenario where the Bazel model is a good fit IMHO. Bazel rebuilds all of your dependencies from source. This makes it easy to compile all of your dependencies with an extra flag (eg -fsanitize=address for ASAN) or using a different compiler (eg Emscripten).
While it can be annoying to wait for the world to rebuild every time, this is a use case where it shines.
I’ll share mine if you share yours:
https://github.com/sorbet/sorbet/tree/master/tools/toolchain...
When we set this up to compile Sorbet (C++ codebase) for https://sorbet.run, it involved what I considered an inordinate amount of boilerplate and arcana.
To be fair since we set it up it’s hardly ever needed to be touched, and I could probably cargo cult this into future projects where I wanted to use it, but I wouldn’t exactly say that bazel magically makes the pain of emscripten go away.
Curious to hear otherwise.
I was under the impression that Emscripten was just an alternative compiler binary, such that you could just use CC=emcc. Is that not the case?
There are projects that provide drop-in support for custom toolchains (e.g., we use this project[0] in Sorbet to fetch and build a custom LLVM/Clang toolchain for every host we build on (rather than relying on the system toolchain). But I'm not aware of a project that has done that for Emscripten. Maybe it would be as easy as plucking out what we've done in our project into a project that others could depend on, but to quote a colleague:
> Setting up a cc toolchain in Bazel is a unique sort of pain.
Why do I need to have a mix? of Python, Java and JS based tools in addition to the C and C++ compilers?
With no option to skip downloading them.
The old code was also very "tight-loop" code that's just math, and no GC allocation, so it's not applicable to many people here yet, and it's possible that JS interpreters have improved since when I ported (GC behavior has gotten quite noticeably better in V8 in the last two years), but I'll take the speedups I can get.
For comparison:
Old TypeScript: https://github.com/magcius/noclip.website/blob/master/src/Co...
New AssemblyScript: https://github.com/magcius/noclip.website/blob/master/src/as...
Wrapper for WebAssembly execution: https://github.com/magcius/noclip.website/blob/master/src/Co...
[0]: https://github.com/WebAssembly/design/blob/master/Nondetermi... [1] A blog post on rollback netcode (not in wasm): https://ki.infil.net/w02-netcode.html
[1] https://stackoverflow.com/a/30919039/225272
[2] https://www.linux.com/training-tutorials/math-v8-broken-how-...
I guess since so many js devs never understood this and built code around one js engines property order behavior they had to go and specify it as a standard and now all js engine must add extra overhead to track and maintain property order...
Not sure how webassembly helps object enumeration order, it doesn't have objects to enumerate! To make objects you compile to webassembly from languages that most likely have undefined dictionary order and may not even have reflection to enumerate an object at runtime.
I think OP is saying that WebAsm allows for using languages that don't have these footguns. Perhaps there is some language they prefer to JS.
Look how much spread there is in the JS, and how little there is in the wasm.
Depending on what you're doing, this may or may not matter to you.
In my case, that would be anything written in Python that targets WebAssembly.
If Javascript is obviated, that's one less programming language mouth to feed.
- An in-browser crossword puzzle generator: https://crossword.paulbutler.org/ (source: https://github.com/paulgb/crossword-composer)
- A multi-player word game: https://redwords.paulbutler.org/
- A library for synchronizing state between clients, used for that word game: https://aper.dev/ (source: https://github.com/aper-dev/aper very WIP right now)
In my experience, the single biggest perk of using WebAssembly is that I can use a language I'm very productive in (Rust) compared to JavaScript. Everything else is secondary. That said, I think these projects have specific advantages by virtue of being WebAssembly:
- The backtracking search used for the crossword puzzle generator is carefully implemented to reduce memory allocations. This would be tough to do in JavaScript, and I believe it's partly responsible for its performance.
- The word game uses a compression algorithm that benefits very noticeably from wasm-opt, to the point that I can't run it without it. Given that wasm-opt takes a non-trivial amount of time at compile time, I suspect the JavaScript JIT would be slow at doing something similar at runtime. This is just conjecture, I haven't checked.
- What Aper does just wouldn't be possible without Rust features like Serde and macros.
It's a design tool that runs entirely in your browser as a WebAssembly-based frontend tool (coded in C++ IIRC). Go kick the tires and play around with it--you will be amazed how fast, fluid and downright native the experience feels.
IMHO I think we're going to see more and more frontend experiences like this in the near future. For certain classes of complex apps we're starting to see the overhead of all the frontend JS cruft, polyfills, reactivity, etc. are just getting out of hand and destroying browsers on low-spec phones and machines. A little Go/C++/Rust/AssemblyScript, etc. app compiled to WebAssembly interacting with the DOM directly is incredibly fast and space efficient. The build system for something like Go or Rust is so much more sane and easy to use vs. a complex modern JS Webpack setup too.
edit: More details here: https://www.figma.com/blog/webassembly-cut-figmas-load-time-...
[1] https://github.com/jeffkaufman/bucket-brigade/blob/master/ht...
I've tried go, rust, c/cpp, webassembly.
go - big bundle sizes because of gc I am guessing, idk.
c/cpp - I haven't touched c/cpp in a really really long time, but probably the other really good fit.
rust - I see rust as the successor to what I would've used c/cpp for, but not sure if rust ecosystem is still fully there. Last time, I had some weird issues with wasm-bindgen.
AssemblyScript(AS) - Something I really like and what I am most comfortable with now that I've been doing java/c#/ts for so long now. Also it's geared towards wasm which is nice. It's my favorite solution, but I don't really get it like I get the other solutions because everything else is an "actual language" that's used for other things. I am really not sure what the strict ts stuff is about, the devil is in the details, and this is getting way too high level.
c# - Maybe good if someone is heavily invested in .net.
At the end of the day, these wasm blobs are probably for heavy tasks like functions with a lot of loops, not full systems, so any simple solution would probably work. It's why I like AS (or even cpp), but sometimes these tasks require some niche external libraries in which case rust would be probably be the best option.
The runtime will eventually be available as well, it is being ported with help of WASI.
Much better option than emscripten and all the machinery it brings along, with three languages (Python, JS, Java).
You can think of WebAssembly as another mechanism for executing code in the browser in the context of a web page. JavaScript is still required to (1) load the wasm binary, (2) evaluate it and (3) connect it to DOM APIs or really anything outside of the isolated wasm execution context.
https://github.com/uBlock-user/uBO-Scriptlets
This wont work with webassembly.
executesitefunction.js could arguably be effected, but that relies on a site installing a particular function on window, which isn't required when using JS, and could be still done where the function is backed by WASM
A lot of stubs, a lot of functionality to kill a script when tripping certain trigger action, or force some properties.
WebAssembly
WebAssembly {compile: ƒ, validate: ƒ, instantiate: ƒ, compileStreaming: ƒ, instantiateStreaming: ƒ, …}
delete WebAssembly
Uncaught ReferenceError: WebAssembly is not defined *##+js(myscript)
does various things, disables webassembly, websocket, AudioContext, serviceworkers, openDatabase and indexedDB, navigator.sendBeacon and window.opener, some fingerprinting randomization stuff, etc. I wish there was a Browser on the market actually letting you configure such things _per domain_ as Opera Presto used to, alas we are on our own now :(. window.console.clear = function arsehole() {console.log(arsehole.caller, "Asshole script called console.clear()")}
before it executesStuff state of the art adblockers (uBO) inject to block ads today: https://raw.githubusercontent.com/uBlock-user/uBO-Scriptlets...
They've been working on adding that for a while in the standard. But it's a complex topic, which is why it is taking time. You can of course bundle your own garbage collector and statically compile it into wasm. That's why Go, C#, etc. can target WASM.
Jetbrains is actually working on a compiler backend for wasm in their new IR compiler for Kotlin. Apparently they are planning to not bundle their own GC and will try to rely on the WASM gc when that is ready. I'm not sure how close they are to having a usable release. But I expect early betas might start happening late this year or next year.