-
Notifications
You must be signed in to change notification settings - Fork 0
Q| What is this project's goal?
A| To allow people to run code on the web, no matter what language it's written in.
Q| How are you trying to do that?
A| Emscripten's strategy is to compile LLVM bytecode into JavaScript, which then allows
- Compiling C/C++ and other code that can be translated into LLVM, directly into JavaScript.
- Compiling the C/C++ runtimes of other languages into JavaScript, and then running code in those other languages in an indirect way. This works for languages like Python and Lua.
Q| Why are you doing this?
A| The web is standards-based, cross-platform, runs everywhere from PCs to iPads, and has numerous independent compatible implementations. It's arguably the best platform to develop for, for those reasons. But it could be even more developer-friendly: While JavaScript (when used well!) is an excellent language, lots of people want to code in other languages.
Q| What is the status of this project?
A| A substantial amount of C/C++, including large projects like CPython, Poppler and Bullet, compiles and run properly, see the demos.
While a lot of stuff already works, expect to find plenty of bugs and rough edges - compiling some random C/C++ code might not currently work due to various small issues. Please file a bug if you encounter code that doesn't compile!
Q| What C/C++ code is expected to be compilable later?
A| The goal is to compile almost all C/C++ code out there, but not all of it - that would require running a bit-for-bit LLVM emulator, which would be slow, and for most C++ code out there, completely unjustified.
An example of code that will not work in this approach: void func(int* y) { char* x = (char*)y; x += 17; y = (int*)x; *y = 10; }. This will confuse Emscripten, but you really don't want to write this kind of C/C++ code anyhow, generally speaking - it isn't portable. If you use pointers 'normally' (including casting to void*, casting to parent/child classes, etc. - stuff that is portable), things will work.
Other limitations are the obvious ones - we will be running in a JavaScript engine. So no threads and so forth (although we may emulate them later on).
Q| How is memory management done?
A| You can use dlmalloc, a popular malloc implementation - it's written in C, and can be compiled into JavaScript using Emscripten (in fact it is one of our automated tests). With that, you will basically be using the same kind of memory management your C/C++ code would use normally.
We also tested with another memory model, of multiple dynamic heaps and letting the JavaScript GC take care of freeing memory automatically. This seems to be slower, so it isn't being focused on currently.
Q| How fast can the generated code get?
A| Right now generated code is 10x slower than gcc -O3 - which is not great, but not that bad either. This will get better with improvements in LLVM, JavaScript optimizers like the Closure Compiler, and JavaScript engines themselves, so expect the generated code to get much faster. There are also plans for additional optimizations that Emscripten itself can perform, which will help significantly as well.
Q| What is the compiler written in?
A| JavaScript. Paralleling the language we are generating code far has various benefits, for example, if we determine some expression can be known at compile time, we can do that immediately in the compiler; otherwise we can simply JSON.stringify() it for the generated code to solve at runtime. Also, (nice) JavaScript is cool.
Q| Isn't it better just to write JavaScript code? Why compile LLVM into JavaScript?
A| By all means write new JavaScript code. Emscripten is just another option to have, and will hopefully be useful if you have a lot of C/C++ code that you don't want to rewrite from scratch. You can still write web applications normally, but Emscripten lets you integrate existing C/C++ code when useful.
Q| How does this relate to similar projects?
A| There are some sort-of-similar things, for example GWT compiles Java into JavaScript, Pyjamas compiles Python into JavaScript, and there was talk of some Adobe project for compiling LLVM into ActionScript for running on Flash. I (kripken) don't know much about any of these projects though.
You can also compare the goals of Emscripten to Google NaCl. NaCl has two main benefits: Reusing existing C/C++ code on the web, and running that code at native speed. Emscripten aims to provide the first of those two benefits, while hoping that JavaScript engines will get so fast that the second benefit will pretty much be achieved as well, and while doing so in a web-friendly way: Emscripten generates JavaScript, that runs on any browser on any platform and device.
Q| Where does Emscripten itself run?
A| It's tested on Linux. In theory it should work anywhere you can get JavaScript and LLVM working (plus Python for the automatic test runner and for emscripten.py), however, non-Linux platforms currently have problems (see our issue tracker). Help with supporting other platforms would be very welcome.
(That's for the compiler. Of course, the generated code is valid JavaScript, so it will run anywhere JavaScript can run.)
Q| What frontends for LLVM can be used? / What can be used to generate LLVM bitcode for Emscripten to then compile into JavaScript?
A| Both Clang and llvm-gcc are supported. Clang is simpler to set up, but might not be able to compile all the C++ code that llvm-gcc does (however it does compile all of our test code successfully).
Using frontends for other languages should be possible, but hasn't really been focused on yet. We would be very happy if someone did, though!
Q| Is this really a compiler? Isn't it better described as a translator?
A| Well, a compiler is usually defined as a program that transforms source code written in one programming language into another, which is what Emscripten does. A translator is a more specific term that is usually used for compilation between high-level languages, which isn't exactly applicable. On the other hand a decompiler is something that translates a low-level language to a higher-level one, so that might technically be a valid description, but it sounds odd since we aren't going back to the original language we compiled from (C/C++, most likely) but into something else (JavaScript).
Q| The name of the project sounds weird to me.
A| I don’t know why; it’s a perfectly cromulent word.
Q| How do I compile code?
A| See Getting Started.
Q| I get lots of errors building the tests.
A| Some common problems are:
- Using older versions of JavaScript engines. Always use the latest, from hg or svn.
- Using older versions of LLVM. The recommended LLVM version is the 2.9 release. Using LLVM trunk might or might not work.
- Typos in ~/.emscripten
Q| My code compiles very slowly...
A| Try compiling with RELOOP = 0 in settings.js. The generated code will be less optimized, but compilation will be much faster.
Q| Why does code compiled with iostream (cout << etc.), or std::string, etc. not work?
A| C/C++ library code, like iostream or std::string, is normally linked to the native code when compiled. With Emscripten, library code that is linked in is in src/library*.js, which currently has the basics of stdio.h in place, but not C++ iostream or std::string stuff.
It should be possible to compile an entire libc++ implementation and use that with your compiled code.
Note that if you compile into LLVM using optimization (with llvm-gcc or clang), it may include the source of some relevant libraries into the .ll file. This is not what Emscripten intends, and results may be odd. Instead, compile without optimization, like the automatic tests do.
Q| My code fails to compile, the error includes something about inline assembly (or {"text":"asm"}).
A| Emscripten cannot compile inline assembly code, which is CPU specific, because Emscripten is not a CPU emulator.
Many projects have build options that generate only platform-independent code, without inline assembly. That should be used for Emscripten. For example, the following might help:
#undef i386 #undef x86_64
since when no CPU-specific #define exists, many projects will not generate CPU specific code. In general though, you will need to find where inline assembly is generated, and how to disable that.
- azakai