In the dying days of the Flash plugin (circa December 2019) I found myself, still doing some legacy support for IE 11 with my ogv.js emscripten codec shim, wondering about another path I had abandoned early on which was to make a Flash build of the codecs with CrossBridge attached to ActionScript 3 code for audio/video output.
My early tests in 2013 or so were that I could build theora and blit output to the screen and it _seemed_ to decode faster than IE's JS engine with the emscripten version but it was a *huge pain in the ass* to build and debug *anything* with the free developer tools I had access to. ;)
CrossBridge was another slightly different platform to accomodate when I already needed a pure-JS version with emscripten, and the compiler was *super slow*. Like it was some weird java build where every cc command launched a fresh VM and took a billion years to jit everything.
Anyway, I ended up minimizing the Flash module to an uncompressed audio output channel (used for IE since it didn't support Web Audio) and stuck with emscripten for JS, and later Wasm & JS builds using the same build scripts and APIs.
BACK TO 2019
So I'm hearing that sometime in 2020 they're gonna pull the plug on the Flash plugin and push a global kill switch. I figure now's the time to find out what I always wondered -- what if I could've had emscripten make me a Wasm, *and* a JS built from the Wasm, *and* a Flash built from the Wasm? Could just a nice transform on the end of your build chain give you a code module you could drop in to any fancy Flash project, if that were to still be a thing in some alternate universe?
And that, plus a few weeks of hypomania, gave birth to wasm2swf...
I took the binaryen Wasm manipulation library, which is used to make the 32-bit normalization transforms for the JS output from emscripten, and built my own code transformation on top of it to flip things around to run on the AVM2 virtual machine in the Flash plugin.
It turns out that you can pretty directly map a lot of stuff in Wasm to AVM2 or with a small transform:
* stack machine -> stack machine
* linear memory -> domain memory
* store addr, val -> store val, addr sort of ordering changes
* branches via block references -> branches via bytecode offset
* args -> args but always with a 'this' in front
* locals -> locals
* functions -> functions/methods
* sign-neutral i32 with sign-specific ops -> i32/u32 types with sign-neutral ops
* f32/f64 -> f64 with a round op
* i64 -> use the same transforms to 32-bit that binaryen has for the JS output
If you want to be frightened with the details the code's still up at github ;)
(note: historical deadname)
https://github.com/bvibber/wasm2swf#wasm2swf
Anyway, I found that I could indeed build the codec modules by literally taking the .wasm output I was already making and transforming it to a .swf (using my own hand-coded AVM2 bytecode assembler and SWF packer from specs -- and I found some errors in the damn specs)
Compared to the JS version from emscripten, the video codecs performed quite well... in IE 11. ;)
Flash was about 2x faster, roughly.
But contemporary 2019-2020 browsers running the Wasm version directly were 2x faster still. :D
And I still would've had to end up debugging the video output layer in Flash manually, and yuck. ;)