extending GHC plugins with Hooks

Luite Stegeman stegeman at gmail.com
Wed Aug 21 04:51:01 CEST 2013


hi all,

Sorry for taking so long to get back with this. I'm proposing a somewhat
general way for adding 'hooks' to the GHC API, where users can override
parts of the default compiling pipeline.

Hooks are simply functions or actions that replace existing compiler
functionality. This means that usually only one application can use a
specific hook at a time.

The obvious data structure to store the hooks is DynFlags. Unfortunately
defining hooks in DynFlags directly would give birth to the mother of all
import cycles, and it would also break the split-dll scheme on Windows. So
here's the idea:

- Define each hook in the module where it's exported
- For each hook make a 'phantom' DataType and an instance for the Hook type
familiy
- Add a TypeRep based map in DynFlags [0]
- For each hooked function, check for existence of a hook in DynFlags,
otherwise run the default. Example:
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L83

Now this approach does have some disadvantages:
- No clear integration with existing plugins (I've tried adding an
onLoadPlugin field to Plugin, where the Plugin could update DynFlags when
it's loaded, but it was a bit messy, and plugins would not be loaded in
time for some hooks, particularly what Edsko needs)
- More of GHC depends on type families
- Decentralized hooks definitions feel a bit messy

So I'm open to suggestions for improvements (or replacements) of this
scheme. I have some time the coming weeks to clean up or change the patch.

We've been testing some hooks with GHCJS for a while, and so far they seem
to provide what we need (but I'm going to doublecheck the coming weeks that
we don't have missing functionality):

- Customizations for linking JavaScript code with our own library locations
[1]
- Hooking into the DriverPipeline so we can use the compilation manager [2]
- Desugaring customizations to remove some C-isms from the FFI code [3]
- Typechecking foreign import javascript imports [4]
- Override the built-in GHC.Prim so we can customize primop types [5]

I think it's easy to add those for Edsko and Thomas as well.

luite

[0]
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L239
[1]
https://github.com/ghcjs/ghcjs/blob/master/src/Compiler/GhcjsHooks.hs#L44
[2]
https://github.com/ghcjs/ghcjs/blob/master/src/Compiler/GhcjsHooks.hs#L192
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L335
[3] https://github.com/ghcjs/ghcjs/blob/master/src/Gen2/Foreign.hs#L67
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L83
[4] https://github.com/ghcjs/ghcjs/blob/master/src/Gen2/Foreign.hs#L68
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L1374
[5]
https://github.com/ghcjs/ghcjs/blob/master/src/Compiler/GhcjsHooks.hs#L191
https://github.com/ghcjs/ghcjs-build/blob/master/refs/patches/ghc-ghcjs.patch#L239

(sorry the linked patch also contains other modifications required for
GHCJS, that i'm going to submit separately)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20130821/1165ffbe/attachment.htm>


More information about the ghc-devs mailing list