[GHC] #7933: JavaScript Cmm backend

GHC cvs-ghc at haskell.org
Tue May 28 01:40:34 CEST 2013


#7933: JavaScript Cmm backend
---------------------------------+------------------------------------------
    Reporter:  bosu              |       Owner:  bosu            
        Type:  feature request   |      Status:  patch           
    Priority:  normal            |   Milestone:                  
   Component:  Compiler          |     Version:  7.6.3           
    Keywords:                    |          Os:  Unknown/Multiple
Architecture:  Unknown/Multiple  |     Failure:  None/Unknown    
  Difficulty:  Unknown           |    Testcase:                  
   Blockedby:                    |    Blocking:                  
     Related:                    |  
---------------------------------+------------------------------------------

Comment(by luite):

 Hi,

 I'm the author of most of the new version of GHCJS that we plan to release
 when GHC 7.8 is released, around ICFP. Most of our RTS works, and we have
 things like preemptive lightweight threading, STM, Fay/UHC-like FFI import
 splices and cross-platform building (running GHCJS on a 64 bit host
 compiler works and gives you efficient JavaScript).

 We have a GHC patch and a Cabal patch, to support doing this as a GHC API
 client, so that we aren't bound to the GHC release schedule in the short
 term, and can prove things work as planned, before (if ever) proposing a
 full merge. Perhaps we can extend this patch to help Josh as well (more
 details about this patch in the next message).

 Boris' approach is different from both Fay and GHCJS in that it translates
 much lower level code to JavaScript. It's different though from the
 current fashion of doing low level JavaScript with asm.js/emscripten, and
 quite original, I must say! (at least I haven't seen this approach to
 pointers before)

 Last summer, when deciding which direction to go with the new GHCJS code
 generator, I briefly explored a similar approach, compiling Cmm to JS. It
 looks appealing, Cmm looks relatively close to imperative JS, you get
 things like stack frame layout optimization and Hoopl dataflow analysis
 for free (we're doing both of these now in GHCJS, but probably not as good
 as the GHC versions).  Ultimately we abandoned the approach due to
 concerns about interoperability with existing JavaScript libraries
 (userfriendliness and easy JS interop are major selling points of Fay) and
 doubts of the feasibility of getting memory management working with it.
 Boris' approach with pointers is different, so it could well be worth
 exploring.

 So the three approaches are quite different:

 * Fay: Directly from Haskell AST to JavaScript, no rewrite rule
 optimization, GHC only used as typechecker, direct function calls (no CPS
 transformation), tail calls to the same function are converted to loops.
 No threads. Very flexible FFI. Generated code is easy to read and you get
 JS stack traces for free.
 * GHCJS: STG to JavaScript: Haskell heap object represented as JavaScript
 objects (except in the cases where JavaScripts own type tagging allows us
 to use primitive types) stacks are JS arrays, CPS transformed code, tail
 calls through trampoline (to be replaced with native JS tail calls when
 (if) they arrive in ECMAScript 6). Threading with eager blackholing, async
 exceptions and STM.
 * Josh: Cmm to JavaScript, interesting approach with closures as pointers,
 performance unknown (it seems that lots of function calls are needed for
 simple operations). Compiling part of the RTS could save a great deal of
 work. Threading possible probably. Looks like the current implementation
 leaks memory.

 I have some questions about memory management in Josh:

 * How do you deal with things that are in native code done by the garbage
 collector. For example when a shared thunk is being computed, it will be
 overwritten by a black hole before the GC is entered, so pointers in the
 thunk aren't followed. It seems that in Josh, the references are retained,
 since they're never overwritten? Also for indirection closures, the GC
 will weed them out, following them, how will you do that?
 * In functions allocating multiple heap objects at once, you start with
 only one fresh Hp, so one object will keep the other alive even if it
 doesn't reference it. Can you reliably fix that?

 Luite

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/7933#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the ghc-tickets mailing list