4 ms·
It would be cool if it compiled either LCC assembly or QVM bytecode to LLVM IR. Now you have all of LLVM's optimizations! Finally, spit out the JS using Emscrip
by jevinskie 13y ago
It would be cool if it compiled either LCC assembly or QVM bytecode to LLVM IR. Now you have all of LLVM's optimizations! Finally, spit out the JS using Emscripten like the rest of the project.
- ris 13y agoI thought that too, but remember this has to all be done at runtime, so depending on LLVM would require an Emscripten-ized version of LLVM (does such a thing exist?) to be distributed with the generated js and similarly depending on Emscripten would require a copy of Emscripten to be distributed with the generated js. And from what I hear the runtime performance of Emscripten itself ain't that great.
- derefr 13y agoWhy does this have to be done at runtime, exactly? How many mods (or rather, QVM files) were there? And are people still making them? If the answer is "less than 100K" and "no, of course not," then you can probably get away with: 1. compiling all the QVM files to their Javascript equivalents ahead-of-time; 2. stuffing them all on a CDN (with each JS blob named after the md5 of the relevant QVM source); and then 3. having a "compiler" in your client that just hashes the source it's about to "compile", and requests the blob with that hash from your CDN. Of course, if the amount of generated JS is small enough, you could even just serve it all with the client. I'm doubting that one, though; it's probably at least 50MB of code. (Though it might be heavily redundant code... it could compress very well!)
- ris 13y ago> Why does this have to be done at runtime, exactly? Because that's how quake3 works. What you're describing would be incompatible with all other quake3 clients. And part of the point of implementing the QVM in the first place is compatibility.
- inolen1 13y agoI actually did that first: https://github.com/inolen/qvmc https://github.com/inolen/qvmc It worked, but the main issue was related to object file generation. Basically, you have to allocate one big i8 array to represent all of the QVM's data segments (including its bss segment). This doesn't translate well once compiled with Emscripten, as bss relocation is on a per-variable basis. For one of the Quake 3 Fortress QVMs which was only a few hundred kb it output a ~50mb .bc file and a ~70mb .js file of mostly 0s. I experimented with storing each segment as its own i8 array (which could be 0 initialized for the bss segment) in a packed struct, which significantly lowered the .bc file size. However, while I was looking into what I'd need to change in Emscripten to support this, I instead decided to go the route of writing the runtime compiler. Fun fact: Quake 3 mods didn't have access to malloc / free, so it wasn't uncommon to have large amounts of static, 0 initialized data.