rubyx/lib/vm/method_compiler/README.md

58 lines
2.5 KiB
Markdown
Raw Normal View History

### Compiling
2014-07-25 10:48:06 +02:00
2016-12-11 11:55:03 +01:00
The typed syntax tree is created by the ruby compiler.
2014-07-25 10:48:06 +02:00
2016-12-11 11:55:03 +01:00
The code in this directory compiles the typed tree to the register machine code, and
Parfait object structure.
2014-07-25 10:48:06 +02:00
If this were an interpreter, we would just walk the tree and do what it says.
2015-03-25 16:29:39 +01:00
Since it's not things are a little more difficult, especially in time.
2014-07-25 10:48:06 +02:00
2015-03-25 16:29:39 +01:00
When compiling we deal with two times, compile-time and run-time.
All the headache comes from mixing those two up.*
2014-07-25 10:48:06 +02:00
Similarly, the result of compiling is two-fold: a static and a dynamic part.
- the static part are objects like the constants, but also defined classes and their methods
2015-07-03 19:13:03 +02:00
- the dynamic part is the code, which is stored as streams of instructions in the MethodSource
2014-07-25 10:48:06 +02:00
Too make things a little simpler, we create a very high level instruction stream at first and then
run transformation and optimization passes on the stream to improve it.
2014-07-25 10:48:06 +02:00
2016-12-11 11:55:03 +01:00
The compiler has a method for each class of typed tree, named along on_xxx with xxx as the type
#### Compiler holds scope
2016-12-11 11:55:03 +01:00
The Compiler instance can hold arbitrary scope needed during the compilation.
2016-12-14 12:22:47 +01:00
A class statement sets the current @type scope , a method definition the @method.
If either are not set when needed compile errors will follow. So easy, so nice.
2014-07-25 10:48:06 +02:00
2015-07-03 19:13:03 +02:00
All code is encoded as a stream of Instructions in the MethodSource.
2015-03-25 16:29:39 +01:00
Instructions are stored as a list of Blocks, and Blocks are the smallest unit of code,
which is always linear.
2014-07-25 10:48:06 +02:00
2015-03-25 16:29:39 +01:00
Code is added to the method (using add_code), rather than working with the actual instructions.
This is so each compiling method can just do it's bit and be unaware of the larger structure
that is being created.
2015-07-03 19:13:03 +02:00
The general structure of the instructions is a graph
(with if's and whiles and breaks and what), but we build it to have one start and *one* end (return).
2014-07-25 10:48:06 +02:00
#### Messages and frames
2016-12-11 11:55:03 +01:00
Since the machine is oo we define it in objects.
2014-07-25 10:48:06 +02:00
2015-03-25 16:29:39 +01:00
Also it is important to define how instructions operate, which is is in a physical machine would
2015-10-23 13:22:55 +02:00
be by changing the contents of registers or some stack.
Our machine is not a register machine, but an object machine: it operates directly on objects and
2015-10-23 13:22:55 +02:00
also has no separate stack, only objects. There is only one object which is accessible,
basically meaning pinned to a register, the Message.
2014-07-25 10:48:06 +02:00
2015-10-23 13:22:55 +02:00
One can think of the Message as an oo replacement of the stack.
2016-12-12 22:38:55 +01:00
When a TypedMethod needs to make a call, it creates a NewMessage object.
Messages contain return addresses (yes, plural) and arguments.
2014-07-25 10:48:06 +02:00
The important thing here is that Messages and Frames are normal objects.