Preserving Flash content with WebAssembly done right [Updated Feb 2020]
Or how we plan to run any Flash content in WebAssembly without re-implementing Flash
This story has been updated on 10 February 2020.
We have received a great amount of interest for this solution, and have been working non-stop since September 2019 to make this into reality. As of February 2020, this solution can run AS2 and AS3 Flash games, as well as Flex/Spark applications. We are working with many Early Adopters, and plan to release a public update before the end of the month.
For quite a long time, and until recently, Adobe Flash has been the tool of choice to create interactive web applications, especially video games. Since Flash is a proprietary technology, people have always been wondering how this content was going to be preserved when, in due time, that technology was going to become obsolete. That time seems now to be around 2020.
The popularity of Flash and the doubts over its legacy were significant enough that the Gnash project, one of the first Free Software attempts at re-implementing Flash, was considered one of the Free Software Foundation high priority projects. Unfortunately, Gnash soon fell behind Adobe’s player in terms of features.
Since Gnash ultimately has not lived up to its promises, there has been no shortage of serious attempts at re-implementing Flash.
- Shumway: a Mozilla sponsored attempt taking advantage of the new (at the time) HTML5 features like Canvas.
- Ruffle: a newly announced Rust re-implementation.
- Lightspark: a C++ implementation.
Among these, my favorite is Lightspark, in part because I wrote a big chunk of it many years ago, but also because Lightspark happens to be, as far as I know, the implementation with the highest level of support for “modern” SWF files - those using ActionScript 3.
If there is one lesson that I learned from working on Lightspark, it is that reimplementing Flash is a very, very, very hard and time-consuming task.
That’s why I am certain that the only practical, robust way to accurately preserve Flash content in the medium and long term is not through a reimplementation. We believe that a different approach is required, and we are working on it right now.
CheerpX: Assembly, but in WebAssembly
Over the last few months, here at Leaning Technologies, we have been working on a breakthrough technology — codenamed CheerpX — to run unmodified x86 binaries in the browser in WebAssembly.
We engineered a WebAssembly virtual machine with a fast interpreter and a JIT engine capable of dynamically recompiling x86 binary to WebAssembly code. This technology is currently in the alpha stage but is good enough to experiment with fully executing unmodified applications in the browser. We will be talking more about this technology in the near future.
As you have probably guessed by this point, our solution to preserve Flash in the long term is to run the full, unmodified, Flash plug-in from Adobe in WebAssembly.
We plan to release more details on how we achieve this as our technology matures. For now, just assume that we have a magic WebAssembly black box that can run x86 binaries. Even with this key piece in place, several more components are needed.
- The Flash plug-in itself: Redistributing the Flash binary is not normally allowed, so we are going to directly download it over HTTP the first time our system is started. The plug-in will be “installed” in the browser using IndexedDB or another persistence API.
- A plug-in host: The Flash plug-in expects to run inside a browser, so we need to write a native x86 host application that will provide a comfortable environment for it. The plug-in build we are using is based on the Pepper API, which is a modern plug-in API (implemented only by Chrome) and originally designed for NaCl modules. This API is decently documented, and we have (partially) implemented it in a binary executable which acts as a bridge between the virtual machine environment and the browser.
- Browser interface: The plug-in host needs access to browser resources, for example, an HTML5 Canvas to draw contents on the screen. The virtual machine environment runs in a Web Worker and has no direct access to the DOM. We serialize relevant commands, for example, “Draw this ImageData at this offset on-screen” and execute these commands in the main thread of the browser.
We have now prototyped all these components and we can actually get some simple Flash content to render on screen.
With this project we are following the same blueprint: we plan to release a Chrome extension, provisionally named CheerpX Flash Runner, that will allow users to run SWF files embedded in pages in a completely seamless way. More in general, this technology will allow playing any legacy Flash content in any WebAssembly-enabled browser.
In the long run, the CheerpX technology will make it possible to run any unmodified binary application in the browser, from productivity apps, to games, to full systems. As much as we would like to release something publicly right now, CheerpX is not yet ready for that.
We will be releasing more details and examples of CheerpX Flash Runner in action in the coming weeks. In the meantime, if you think our Flash project or CheerpX, in general, might be interesting for you. Feel free to get in touch with us at firstname.lastname@example.org.