My Apple compiler started as an experiment in what I would implement as compiler for an array system. Several parts did not pan out so I offer my warnings and advice to other array language implementers.
Functions are compiled to machine by a convention of jumps and
registers; one calls a function by jumping to its
location in memory. These jumps are relative and particular functions (say,
malloc
) may be loaded at different memory locations, so the machine code for
a function cannot be pinned down and in fact is contingent on every function
that it calls.
Building a respectable compiler requires basic blocks in order for liveness analysis to be performant. Consider my own Apple compiler:
Writing a practical JIT is somewhat complicated and in fact depends on the
assembler; here I present a full example in Haskell. Notably this JIT/assembler
is capable of calling procedures in system libraries (i.e. malloc
, free
)