Skip to content

CodeGuidlinesAndLimitations

kripken edited this page Apr 4, 2012 · 10 revisions

Emscripten can work with pretty much any C/C++ code. However, it might be useful to know what types of code Emscripten compiles better than others, if you are rewriting part of the code you will be compiling.

Code that CANNOT be compiled

These issues are fundamental difficulties. We can get around them by emulation in theory, but it would be very slow.

  • Code that is multithreaded and uses shared state. JS has threads - web workers - but they cannot share state, instead they pass messages.
  • Nonportable code that relies on endianness is problematic. It can work with USE_TYPED_ARRAYS=2, but it will not be portable!
  • Code that uses low-level features of the native environment, like native stack manipulation (e.g. in conjunction with setjmp/longjmp. We support normal setjmp/longjmp, but not with stack replacing etc.).

Code that DOES compile, but might be slower than expected

None of the issues here is a showstopper, but they might be slower than you expect. You probably don't need to worry about this stuff, but it might be useful to know about it.

  • 64-bit ints. Bitwise operations on these are reasonable, but math (+, -, *, /) is emulated, very slowly. JavaScript does not have native 64-bit ints so this is unavoidable.
  • 32-bit floats will end up as 64-bit doubles in JS engines. That means they might be a little slower than expected, depending on your CPU.
  • memcpy/memset works, but JS engines don't optimize it very well. Native code will use SIMD on this, JS engines will not - yet.
  • Structures/classes. Unlike simple variables, they are not yet nativized in Emscripten, which adds some overhead. Inner loops that do property accesses, for example, might be rewritten to avoid this.

Code that MIGHT be useful to avoid

Avoiding these kinds of code might be nice to do, to prevent warnings and to enable additional optimizations. But unless it is very easy for you to avoid them, just ignore this section.

  • Unions. These will trigger SAFE_HEAP warnings (like valgrind), and make the QUANTUM_SIZE=1 optimization impossible.
  • Bitfields. Also SAFE_HEAP warnings.
  • Reusing memory, that is, using the same allocated block of memory once for one kind of object, later for another. This prevents the QUANTUM_SIZE=1 optimization.

Clone this wiki locally