Saturday, April 30, 2011

RPython to Javascript


RPythonic 0.3.1 now integrates with the fantastic Emscripten project to allow conversion of RPython into Javascript. PyPy itself had an experimental backend for Javascript, but this was recently removed because no one was maintaining it. Emscripten is more useful in any case because it will allow for the translation of C libraries used within RPython/RFFI. The PyPy backend would have been limited to only translating RPython code.

Translation begins with passing the RPython entry-point to rpy.compile(). Compile will then take care of translating to C, passing to Emmaken and LLVM, disassemble the LLVM binary, optimize with Emscripten's remove-dead-functions, pass that to emscripten.py to generate the javascript, and finally optimize the javascript with Closure. The result is 6,000 lines of javascript, most of which is RPython's reference counting garbage collector.

To make RPythonic easy to install several things are now included:

  • prebuilt d8 (google v8 javascript interpreter)

  • Emscripten configured for Ubuntu 11.04

  • Closure

  • PyCparser

  • CppHeaderParser

11 comments:

  1. Very cool!

    So could this be used to translate the PyPy interpreter into JavaScript, and run it on the web?

    ReplyDelete
  2. It should be able to, just pass the pypy entry point function to rpy.compile. But my guess is it would be slower than your cpython test, because pypy is half cpython speed without its jit.

    ReplyDelete
  3. Under Ubuntu Natty x64 with LLVM 2.8 (official) and 2.9 (downloaded in binary from llvm.org), trying to compile a simple use case I'm getting:

    ../pypy/pypy/translator/c/src/commondefs.h:58:6: error: #error "error in LONG_MAX (64-bit sources but a 32-bit compiler?)"
    ../pypy/pypy/translator/c/src/commondefs.h:61:6: error: #error "unsupported value for LONG_MIN"

    Have you tested this in a 64 bit platform? Any pointers?

    ReplyDelete
  4. I hardly recognize my CppHeaderParser :)

    -Jash

    ReplyDelete
  5. Hi Mi,
    Sorry i gave up on 64bit since i am making sure that i can target Android and need 32bit output, and there is no way yet for force PyPy to output 32bit code from a 64bit host (even if you compile your own 32bit on the 64bit host, because of the way PyPy interacts with GCC i guess). I am running Ubuntu 11.04 32bit.

    ReplyDelete
  6. Hey Hart, it turns out it wasn't so complicated after all. I put up a recipe in my blog: http://mdqinc.com/blog/2011/05/from-python-to-javascript-the-scenic-route/
    I can add an issue in the Google Code tracker if you want, and attach the compiled V8 for 64 bits if you want, not sure how you can handle the PyPy patching in an automated way though (you can always mention it in the docs)

    ReplyDelete
  7. Sounds exciting.
    Anybody got an example to link to?
    (an example of code made with it compiled and running somewhere online?)
    What kinda load time and file sizes are we talking about?

    ReplyDelete
  8. Hi LukeStanley,

    The file size is going to be at least 200KB, I don't think Gabriel (mi), see his comment above, has posted his translation result on his website. He was actually the first to get everything working, by solving some obscure bugs via some serious Dr.House-style investigation. Props to Gabriel, i will be included his fixes in the 0.3.6 release of RPythonic.

    ReplyDelete
  9. ok thanks Hart, I posted on his post.

    ReplyDelete
  10. Given that pyglet works on pypy, how easy would it be to get it working with webgl?

    ReplyDelete
    Replies
    1. Luke, sorry for the late reply, there is a better method now for translating Python into Javascript, see my recent blog posts about "PythonScript". I am also working on PythonScript with WebGL integration wrapping the THREE.js library.

      Delete