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

apfelmus apfelmus at quantentunnel.de
Sat May 12 05:18:03 EDT 2007


Dirk Kleeblatt wrote:
> Bas van Dijk wrote:
>> Regarding the use of labels, did you consider using "circular
>> programming with recursive do" to define and reference labels like in:
>>
>> Russell O'Connor, Assembly: Circular Programming with Recursive do
>> http://haskell.org/sitewiki/images/1/14/TMR-Issue6.pdf
> 
> Yes, we considered this technique, but we came to the conclusion that it
> is not applicable in our setting: we are writing directly to malloc'ed
> memory, so our operations are strict in the label parameter. Thus, the
> fixpoint of the recursive mdo would be bottom.
> 
> However, these were (up to now) only theoretical thoughts, maybe our
> hypothesis of strict operations can be weakened.

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
      loopTest  <- newLabel
      loopStart <- newLabel
      ensureBufferSize 160
      push ecx
      mov  ecx (Disp 8, esp)
      mov  eax (1 :: Word32)

(1)   jmp  loopTest

      loopStart @@ mul ecx
      sub  ecx (1 :: Word32)

(2)   loopTest @@ cmp ecx (0 :: Word32)

      jne  loopStart
      pop  ecx
      ret

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).

Also, the explicit declaration of labels has an inherent safety problem.
Namely, nobody prevents you from using a label twice, like for example in

     loopStart @@ mul exc
     ...
     loopStart @@ cmp ecx (0 :: Word32)

Declaring a label (via f.i.)

     loopStart <- mul exc

at it's instruction doesn't have this problem.


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

In short, it looks like the "CodeGen e s a"-monad eagerly writes code
without doing much book-keeping. I think that changing this enables
recursive do.

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.

Regards,
apfelmus



More information about the Haskell mailing list