Saturday, April 9, 2011

Emscripten 1.0!

It's been almost a year since I started Emscripten (which, if you haven't heard of it, is a tool to compile LLVM to JavaScript), during which it took up much of my spare time. So I am very pleased to announce that today Emscripten has reached the 1.0 milestone. This release comes with a demo of rendering PDFs on the web (warning: that page downloads >12MB, since it includes Poppler and FreeType. It's like downloading an entire desktop app, almost).

Other highlights in this release:
  • Very significant optimization of memory use in the compiler. This was necessary for the PDF demo to build, since it is far larger than previous demos.
  • Full support for the recently released LLVM 2.9.
  • The Emscripten documentation paper is finished. It explains how Emscripten works, so you might be interested in it if you care what Emscripten does under the hood (but if you just want to use Emscripten you don't need to read it).
Overall Emscripten is now in very good shape. It can probably compile most any C/C++ project out there, subject to some limitations (like JS not allowing C-style multithreading). At times some manual intervention is needed, like changing the project's settings so it doesn't generate inline assembly, and of course bugs probably still exist, but recently the code I have compiled has tended to just work (hence the rate of commits has greatly decreased recently).

The speed of the generated code can be quite good. By default Emscripten compiles with very conservative settings, so the code will be slow, but optimizing the code is not that hard to do. Optimized code tends to run around 10x slower than gcc -O3, which is obviously not great, but on the other hand fairly decent and more than good enough for many purposes. And of course, that ratio will improve along with advancements in JavaScript engines, LLVM, and the Closure Compiler.

So, Emscripten 1.0 is in my opinion pretty solid. There are no major outstanding bugs, and no major missing features. (But I do have plans for some major improvements, which are difficult, but should end up with code that runs at least twice as fast.) Now that Emscripten is at 1.0, I am hoping to see it used in more places. I'm starting to propose at Mozilla that we use it in various ways, and also I'd love to see things like GTK or Qt ported to the web - if anyone wants to collaborate on that, let me know.

8 comments:

  1. Does emscripten use a giant "memory" array, or does it manage to compile individual C objects to individual JavaScript objects?

    How much of a C library do you have?

    ReplyDelete
  2. @Anon:

    1. It uses a giant memory array. I have plans to create JS objects for C structs, but that will be hard.

    2. There is enough of a C library to run all the demos. So that is quite a lot, but probably lots of little stuff missing. It is possible though to compile an entire libc from C into JS and use that (only need to hook up the lower-level stuff where it calls the OS).

    ReplyDelete
  3. Sounds like it would be a good match for the existing GTK+ HTML backed work...

    ReplyDelete
  4. Congrats on the 1.0 release. I'm definetly looking forward to coding my next web based RIA in C++!! Was wondering if emscripten supports javascript event callbacks (for eg., coding for the Browser DOM in C++ through javascript callbacks into llvm functions).Any examples or pointers would be great!

    ReplyDelete
  5. @sam

    There isn't any specific support for that, mainly since I'm not sure what kind of API would be right. But you can already do this sort of thing by writing

    emscripten_run_script(" ... ");

    in your C++ code. That will run the text in eval() in the browser. So you can manipulate the DOM there, for example

    emscripten_run_script("window.alert('hello world!')");

    would show an alert, etc. And you can generate the proper string in C++ to do whatever you want.

    ReplyDelete
  6. This project is the bomb!
    Nice work Kripken

    ReplyDelete
  7. HOLY F****IN CR*P!! This is the best project ever! thanks a million! This will certainly be useful for web-izing my existing apps.

    ReplyDelete
  8. I can't believe I didn't see your work before.

    I'm currently working on a html5 port of Qt 4.8.0!

    You can see some primitive demos on my website.

    I'd really like to grind QtCore and QtGui out through enscript, but of course there's the canvas, mouse/keyboard handling and mouse cursors which I kind of have working, in Google Chrome anyway.

    Check out http://developer.qt.nokia.com/forums/search_results/dd0547661be85505352530eb89570aac/

    for my posts.

    I'm hitting a brick wall getting enscript running on Debian amd64 (I set up debugging).

    Here's the .js file for
    python tests/runner.py clang_0_0.test_hello_world:

    // ll ==> meta: {"11":"0","12":"7","13":"8","14":"8"}
    // meta ==> sline: {"0":"5","2":"458798","7":"6","8":"7"}
    // meta ==> pmeta: {"0":"1","2":"3","7":"1","8":"2"}
    // meta ==> fname: {}
    // starting to recurse metadata for: 0
    // recursing metadata, at: 0
    // recursing metadata, at: 1
    Assertion failed: Confused as to parent metadata for llvm #11, metadata !undefined
    Stack: Error
    at assertTrue (utility.js:60:23)
    at Object.processMetadata (modules.js:113:9)
    at intertyper (intertyper.js:24:24)
    at /v3c/dev/Graphics/html5/kripken-emscripten-5b3b4c5/src/compiler.js:79:16
    utility.js:61: Assertion failed: Confused as to parent metadata for llvm #11, metadata !undefined
    throw msg;
    ^

    ReplyDelete