apfelmus wrote:
Dirk Kleeblatt wrote:
apfelmus wrote:
[...]
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.

Ah, I slowly get what you mean. In short, the point is that you're
reinventing lazy evaluation because you're writing directly to a memory
buffer and writing a raw _|_ is impossible. So, you invent a scheme to
delay the evaluation of the _|_ until they are defined.

Exactly.

I thought that you'd simply store the instructions in a list/monoid like
the Builder-Monoid from Data.Binary

Currently, we don't.

Here's an illustration with a fictional robodog toy assembly language

  import Control.Monad.RWS

  type Address = Int
  data Dogcode = Bark | Bite | Jump Address

Nice! :-)

If you really want to directly write to a memory buffer,

It makes interleaving code generation, execution of the buffer, generating more code, executing a little bit and so on (see below) easier, but...

However, because of omnipresent lazy evaluation, it is unclear whether
"directly" writing to a buffer instead of first building a monoid does
give a speed/space advantage. So, your current approach may well be
slower than a naïve "first (difference) list, then raw memory" approach.

... after seeing some benchmarks in the last hours, I guess this is right: Doing the optimizations that the binary package does might give laziness and speed at the same time.

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.

Huh, I thought that runCodeGen would do an additional backpatch pass as
transparently?

Currently, it doesn't. And in the current implementation, it's not necessary.

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

Huh? That means that code gets executed during it's own generation? But
why do you mix separate concerns? I don't see what use this is besides
being an opportunity to mess up.

One of our projects is a just-in-time compiler for a functional language. Here, compilation is done lazily: A starting stub is compiled and executed, when the execution reaches some point for which no code has been generated yet the next bit of code is compiled, and the program is resumed, and so on. So execution and code generation are interleaved.

Another project is related to dependent type checking as described by Benjamin Grégoire and Xavier Leroy in [1]. Here, functions can occur in types, and the cited paper describes how these functions can be executed by compiled code. During type checking. So type checking, code generation, and execution are interleaved.

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.

Huh, why does the user have to care? Shouldn't wrapping the raw memory
block into a Foreign.ForeignPtr do the job?

Well, both projects manage a separate memory block which is used like a heap by generated code. This heap contains closures that have code pointers into generated code. And these are subject to our (not yet implemented... ;-) ) garbage collectors, not the Haskell collector.

Kind regards,
  Dirk

[1] http://pauillac.inria.fr/~xleroy/publi/strong-reduction.pdf

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to