ruby-x.github.io/app/views/posts/_2014-07-05-layers-vs-passes.html.haml
2018-04-10 19:50:07 +03:00

45 lines
2.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

%p I am not stuck. I know im not. Just because there is little visible progress doesnt mean im stuck. It may just feel like it though.
%p But like little cogwheels in the clock, i can hear the background process ticking away and sometimes there is a gong.
%p What i wasnt stuck with, is where to draw the layer for the vm.
%h3#layers Layers
%p
Software engineers like layers. Like the onion boy. You can draw boxes, make presentation and convince your boss.
They help us to reason about the software.
%p
In this case the model was to go from ast layer to a vm layer. Via a compile method, that could just as well have been a
visitor.
%p
That didnt work, too big astep and so it was from ast, to vm, to neumann. But i couldnt decide
on the abstraction of the virtual machine layer. Specifically, when you have a send (and you have
soo many sends in ruby), do you:
%ul
%li model it as a vm instruction (a bit like java)
%li implement it in a couple instructions like resolve, a loop and call
%li go to a version that is clearly translatable to neumann, say without the value type implementation
%p
Obviously the third is where we need to get to, as the next step is the neumann layer and somewhow
we need to get there. In effect one could take those three and present them as layers, not
as alternatives like i have.
%h3#passes Passes
%p
And then the little cob went click, and the idea of passes resurfaced. LLvm has these passes on
the code tree, is probably where it surfaced from.
%p
So we can have as high of a degree of abstraction as possible when going from ast to code.
And then have as many passes over that as we want / need.
%p
Passes can be order dependent, and create more and more detail. To solve the above layer
conundrum, we just do a pass for each of those options.
%p The two main benefits that come from this are:
%p
1 - At each point, ie after and during each pass we can analyse the data. Imagine for example
that we would have picked the second layer option, that means there would never have been a
representation where the sends would have been explicit. Thus any analysis of them would be impossible or need reverse engineering (eg call graph analysis, or class caching)
%p
2 - Passes can be gems or come from other sources. The mechanism can be relatively oblivious to
specific passes. And they make the transformation explicit, ie easier to understand.
In the example of having picked the second layer level, one would have to patch the
implementation of that transformation to achieve a different result. With passes it would be
a matter of replacing a pass, thus explicitly stating “i want a non-standard send implementation”
%p Actually a third benefit is that it makes testing simpler. More modular. Just test the initial ast->code and then mostly the results of passes.