UHC-like JavaScript backend in GHC

J. Stutterheim j.stutterheim at me.com
Tue Nov 13 20:31:37 CET 2012

On 13 Nov 2012, at 19:08, Luite Stegeman <stegeman at gmail.com> wrote:

> On Mon, Nov 12, 2012 at 9:16 AM, Jurriën Stutterheim
> <j.stutterheim at me.com> wrote:
>> Hi all,
>>  foreign import js "%1.push(%2)"
>>    push :: JSArray a -> a -> IO (JSArray a)
> I'm not sure if it's even necessary to extend GHC itself for this.
> Even though this exact syntax (with the js calling convention name) is
> not supported, the import pattern is available as a string at compile
> time [1], so you can easily generate the desired code with a compiler
> that uses the GHC API. I work on GHCJS [2], a compiler that generates
> Javascript from STG.

That's an interesting approach too. If you're writing a new compiler which uses the GHC API, I agree there is probably no real need to create a separate js calling convention, although using a C calling convention for JS code might be a bit confusing. Indeed, the string is sufficient for generating the required code. UHC's string parser can probably easily be ported, as can some of the code generation parts.

Does/can cabal-install support GHCJS? I suppose that's a minor advantage of extending GHC itself; you get cabal support almost for free.

> Unfortunately, GHCJS is in a state of flux at the moment so it's a bit
> hard to come up with a proof of concept implementation at this point.
> I started a complete rewrite a few months ago, because the old version
> didn't have the performance I needed. The new version [3] appears to
> generate much faster code, but a lot of things (including FFI) have
> not yet been implemented. It's still a bit too early to tell if the
> new code generator can fully replace the old one.

How big are the JS files generated with either the new or the old code generator? I recall there was a HS -> JS effort out there that generated huge JS files. UHC's output is relatively compact and doesn't grow as fast with bigger programs.

> I would like to add the friendlier FFI syntax later, but as far as i
> can see, it should be pretty straightforward to do this... (at least
> compared to supporting many of the other GHC features in JS)

Sounds like it would be pretty straightforward, yes.

> WebWorkers might not be able to do what you need for concurrency,
> since the ways you can communicate between them are really limited,
> you have to serialize everything, no shared data. This is why GHCJS
> has its own scheduler [4] in the RTS.

WebWorkers is quite limited indeed. I'm not yet sure how the serialisation might complicate matters, but it seems that WebWorkers is only really a possible backend for `fork`, and not `forkIO`.

> luite
> [1] http://www.haskell.org/ghc/docs/7.6.1/html/libraries/ghc-7.6.1/ForeignCall.html#t:ForeignCall
> [2] GHCJS - https://github.com/ghcjs/ghcjs
> [3] GHCJS new code generator - https://github.com/ghcjs/ghcjs/tree/gen2
> [4] GHCJS scheduler -
> https://github.com/ghcjs/ghcjs/blob/master/rts/rts-trampoline.js#L244


More information about the Glasgow-haskell-users mailing list