[Haskell] Re: ANNOUNCE: Harpy -- run-time code generation library
klee at cs.tu-berlin.de
Mon May 14 11:31:57 EDT 2007
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
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