jotting ideas

This commit is contained in:
Torsten Ruger 2015-05-07 00:07:26 +03:00
parent 531cfdd7eb
commit 933e256774
2 changed files with 120 additions and 0 deletions

View File

@ -0,0 +1,77 @@
---
layout: site
author: Torsten
---
Since i got the ideas of Slots and the associated instruction Set, i have been wondering how that
fits in with the code generation.
I moved the patched AST compiler methods to a Compiler, ok. But still what do all those compile
methods return.
## Expression
In ruby, everything is an expression. To recap "Expressions have a value, while statements do not",
or statements represent actions while expressions represent values.
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.
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.
## Return slot
Today i realized that the Slot representing the return value is special.
It does not hold the value that is returned, but rather the other way around.
A function returns what is in the Return slot, at the time of return.
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.
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!
## Example
Constants: say the expression
true
would compile to a
ConstantLoad(ReturnSlot , TrueConstant)
While
2 + 4
would compile to
ConstantLoad(ReturnSlot , IntegerConstant(2))
Set(ReturnSlot , OtherSlot)
ConstantLoad(ReturnSlot , IntegerConstant(4))
Set(ReturnSlot , EvenOtherSlot)
MethodCall() # unspecified details here
## Optimisations
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.
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
ConstantLoad(ReturnSlot , IntegerConstant(2))
Set(ReturnSlot , OtherSlot)
can easily be optimized into
ConstantLoad(OtherSlot , IntegerConstant(2))
tbc

View File

@ -0,0 +1,43 @@
---
layout: site
author: Torsten
---
As noted in previous posts, differentiating between compile- and run-time is one of the more
difficult things in doing the vm. That is because the computing that needs to happen is so similar,
in other words almost all of the vm - level is available at run-time too.
But off course we try to do as much as posible at compile-time.
One hears or reads that exactly this is a topic causing (also) other vms problems.
Specifically how one assures that what is compiled at compile-time and and run-time are
identical or at least compatible.
The obvious answer seems to me to **use the same code**.In a way that "just" moves the question
around a bit, becuase then one would have to know how to do that. I'll go into that below,
but find that the concept is worth exploring first.
Let's take a simple example of accessing an instance variable. This is off course available at
run-time through the function *instance_variable_get* , which could go something like:
def instance_variable_get name
index = @layout.index name
return nil unless index
at_index(index)
end
Let's assume the *builtin* at_index function and take the layout to be an array like structure.
As noted in previous posts, when this is compiled we get a Method with Blocks, and exactly one
Block will initiate the return. The previous post detailed how at that time the return value will
be in the ReturnSlot.
So then we get to the idea of how: We "just" need to take the blocks from the method and paste
them where the instance variable is accessed. Following code will pick the value from the ReturnSlot
as it would any other value and continue.
The only glitch in this plan is that the code will assume a new message and frame. But if we just
paste it it will use message/frame/self from the enclosing method. So that is where the work is:
translating slots from the inner, inlined fuction to the outer one. Possibly creating new frame
entries.
tbc