[Haskell] Re: ANNOUNCE: Harpy -- run-time code generation library

Dirk Kleeblatt klee at cs.tu-berlin.de
Mon May 14 11:31:57 EDT 2007

apfelmus wrote:
> Note that even currently, your operations cannot be strict in the
> address a label refers to because this may be determined later than the
> first use of the label. In other words, your example code
>   fac = do
> (1)   jmp  loopTest
> (2)   loopTest @@ cmp ecx (0 :: Word32)
> already shows that the function jmp that generates a jmp-instruction may
> not be strict in the position it jumps to as the address behind loopTest
> is only known later at line (2).

When generating code for (1), the label loopTest is used as an index 
into a map, to see whether there's a code position associated with it. 
If it is, the code position is used to compute the jump offset for the 
jmp instruction, if not (as in this example), a dummy value is placed in 
the code buffer, and Harpy remembers this position to be patched later 
on. At (2), the label is defined, and this leads to patching all 
instructions that have been emitted before this definition.

So, yes, the code position is only used after the definition of the 
label. But the "look up in a map"-part makes the jmp operation strict in 
the label parameter.

We could omit the map, and just remember where to patch the code, but 
then we'd need to call explicitly some function after code generation 
that does the patching. We had implemented this, but found the current 
solution easier to use, since backpatching is completely automatic and 
hidden from the user.

However, this is just a description of the current implementation, not 
an argument that there's no better implementation. Probably there is, 
maybe using the binary package.

> Also, the explicit declaration of labels has an inherent safety problem.
> Declaring a label (via f.i.)
>      loopStart <- mul exc
> at it's instruction doesn't have this problem.

This looks quite elegant, I'll think about it...

> Furthermore, having to call 'ensureBufferSize 160' is very strange for
> this is data that can be calculated automatically.

As I wrote at haskell-cafe, we require this only for performance 
reasons, to keep buffer overflow checks as seldom as possible. But there 
might be better ways to do this.

> I also think that having liftIO in the CodeGen-monad is plain wrong. I
> mean, CodeGen is a monad that generates code without any execution
> taking place. The execution part is already handled by runCodeGen.
> Having liftIO means that arbitrary Haskell programs can be intertwined
> with assembly generation and I doubt that you want that.

Feel free to doubt, but this is exactly what we want. :-)

Also, note that runCodeGen runs the code _generation_, executing the 
generated code is done _within_ the CodeGen monad via the functions 
generated by callDecl (or the predefined functions in the Harpy.Call 
module). This is even more intertwined, but intentional.

Of course, again a different design is possible, making runCodeGen 
return a binary code object, that can be called from the IO monad. But 
then, the user has to care about releasing code buffers, and not to have 
unevaluated closures having code pointers to already released run-time 
generated code.

Kind regards,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3212 bytes
Desc: S/MIME Cryptographic Signature
Url : http://www.haskell.org/pipermail/haskell/attachments/20070514/a2091758/smime-0001.bin

More information about the Haskell mailing list