ruby-x.github.io/app/views/posts/_2015-05-20-expression-is-slot.haml

72 lines
2.6 KiB
Plaintext
Raw Normal View History

2018-04-10 18:50:07 +02:00
%p
Since i got the ideas of Slots and the associated instruction Set, i have been wondering how that
fits in with the code generation.
%p
I moved the patched AST compiler methods to a Compiler, ok. But still what do all those compile
methods return.
%h2#expression Expression
%p
In ruby, everything is an expression. To recap “Expressions have a value, while statements do not”,
or statements represent actions while expressions represent values.
%p
So in ruby everything represents a value, also statements, or functions. There is no such thing
as the return void in C. Even loops and ifs result in a value, for a loop the last computed value
and for an if the value of the branch taken.
%p
Having had a vague grasp of this concept i tried to sort of haphazardly return the kind of value
that i though appropriate. Sometimes literals, sometimes slots. Sometimes “Return” , a slot
representing the return value of a function.
%h2#return-slot Return slot
%p Today i realized that the Slot representing the return value is special.
%p It does not hold the value that is returned, but rather the other way around.
%p A function returns what is in the Return slot, at the time of return.
%p
From there it is easy to see that it must be the Return that holds the last computed value.
A function can return at any time after all.
%p
The last computed value is the Expression that is currently evaluated. So the compile, which
initiates the evaluation, returns the Return slot. Always. Easy, simple, nice!
%h2#example Example
%p Constants: say the expression
%pre
%code
:preserve
true
%p would compile to a
%pre
%code
:preserve
ConstantLoad(ReturnSlot , TrueConstant)
%p While
%pre
%code
:preserve
2 + 4
%p would compile to
%pre
%code
:preserve
ConstantLoad(ReturnSlot , IntegerConstant(2))
Set(ReturnSlot , OtherSlot)
ConstantLoad(ReturnSlot , IntegerConstant(4))
Set(ReturnSlot , EvenOtherSlot)
MethodCall() # unspecified details here
%h2#optimisations Optimisations
%p
But but but i hear that is so totally inefficient. All the time we move data around, to and from
that one Return slot, just so that the return is simple. Yes but no.
%p
It is very easy to optimize the trivial extra away. Many times the expression moves a value to Return
just to move it away in the next Instruction. A sequence like in above example
%pre
%code
:preserve
ConstantLoad(ReturnSlot , IntegerConstant(2))
Set(ReturnSlot , OtherSlot)
%p can easily be optimized into
%pre
%code
:preserve
ConstantLoad(OtherSlot , IntegerConstant(2))
%p tbc