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 _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell