Today I wanted to try a very basic web experiment that I had in mind for some time.
The idea was to code in C++ inside the browser and see the output right there.

If you want to know how it is done read the full entry.
How it works
There are three ways of doing that:
- Compiling the C++ code to some sort of VM and executing that VM right in the browser
- Sending the code to the server, compiling it using a regular C compiler, executing it and sending the console output to the browser.
- Sending the code to the server, transpiling it to JS, sending that JS to the browser and executing it there.
The first option would be very interesting, sadly I couldnt find any C++ compiler in JS or a 8086 CPU emulator in JS.
The second one could be done with some tricks on the server (redirecting the execution output through websocket to the browser), but the main problem is that it is very dangerous, somebody could send malicious code that would be executed in my host, which means sandboxing… bad road.
But the thirth one is very easy once you have the transpiler.
Some time ago I was playing with libraries compiled in Emscripten, but I never tryed to compile my own C++ code to JS, so this could be a nice experiment to see how easy is to convert C++ code to JS.
The app works by sending the code to the back-end where I call emscripten compiler command (emcc) and retrieve the resulting code and the compiler output (to catch errors and warnings).
Compiling
The simplest helloworld weights around 200KBs of JS, mostly from stdio. Depending on the complexity of the code the compilation time could go from 5 seconds (the time the compiler needs to start running) to several minutes (causing a time out). And the complexity could grow just by including a library (p.e. including iostream increases the end JS size by 2 MBs and the compilation time takes 20 seconds more).
So this is not a straight solution to code full C++ applications on the web, it is more like a proof of concept. It would be interesting to investigate more about possible optimizations done by the compiler. As far as I know emscripten caches the results to speed up future compilations and I saw it after including some libraries for the first time, but it is hard to know what are best practices when working with emscripten in this way.
In my case to speed up a little bit the results I cache the generated JS using the md5 of the code. This way I can skip the compilation if the file was compiled before, by using more hard drive (I will have to keep an eye in that folder or it could grow to several GBs).
You need to play with the compiler parameters to get the best results, for instance, I wanted to be able to control when the main function will be called, instead of the default behavior which is executing it right when the script file is parsed. Also I wanted to overwrite some functions so I could integrate the execution with my interface.
Using Workers
One of the problems I found was that if the code entered in an infinite loop (or is doing some intensive computations) it will crash the tab. To solve that I decided to move the execution to a WebWorker, this way the main thread of Javascript is safe and I can kill the executing process whenever I want.
All the IO calls (printf,…) from the script must be redirected through postMessage to the main thread, but that’s something I already did for another project.
I’m planning to create a tiny framework that allow to render pixels on the screen using a canvas so I can try coding some basic effects right in the browser using C++.
Feel free to use it but be careful and do not over use it, the compiler is kind of CPU consuming for my tiny host.
If you want to improve it, all the code is in github right now. 🙂
Leave a Reply