2d39825547
still doesn’t do it justice, but at least it’s not wrong anymore and does have a link to the book
149 lines
6.2 KiB
HTML
149 lines
6.2 KiB
HTML
---
|
|
layout: salama
|
|
title: Salama, a simple and minimal oo machine
|
|
---
|
|
|
|
|
|
<div class="row vspace10">
|
|
<div class="span12 center">
|
|
<h3><span>Salama layers</span></h3>
|
|
<p>Just a small primer (left over from the start), really <a href="http://dancinglightning.gitbooks.io/the-object-machine/content/">the book</a> is the best starting point</p>
|
|
</div>
|
|
</div>
|
|
<div class="row vspace20">
|
|
<div class="span11">
|
|
<h5>Machine Code, bare metal</h5>
|
|
<p>
|
|
This is the easy to understand part, that's why it's first, it's the code
|
|
from <a href="https://github.com/salama/salama-arm"> salama-arm </a>, which is quite stable.
|
|
It creates binary code according to the arm specs. All about shifting bits in the
|
|
right way.
|
|
<br/>
|
|
As an abstraction it is not far away from assembler. I mapped the memnonics to function calls and the registers
|
|
can be symbols or Values (from vm). But on the whole this is as low level as it gets.
|
|
<br/>
|
|
Different types of instructions are implemented by different classes. To make machine dependant code possible,
|
|
those classes are derived from Vm versions.
|
|
<br/>
|
|
There is an intel directory which contains an expanded version of wilson, but it has yet to be made to fit into
|
|
the architecture. So for now salama produces arm code.
|
|
<br/>
|
|
There is an elf directory wich builds actual executables, a mini implementation of the elf standard.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Parsing, forever descending</h5>
|
|
<p>
|
|
Parsing is relatively straightforward too, it's code is found in <a href="https://github.com/salama/salama-reader">
|
|
it's own repository </a>.
|
|
It parses more than can be processed, but much less than ruby is.
|
|
<br/>
|
|
We all know ruby, so it's just a matter of getting the rules right.
|
|
If only! Ruby is full of niceties that actually make parsing it quite difficult. But at the moment that story
|
|
hasn't even started.
|
|
<br/>
|
|
Traditionally, yacc or bison or talk of lr or ll would come in here and all but a few would zone out. But llvm has
|
|
proven that recursive descent parsing is a viable alternative, also for big projects. And Parslet puts that into
|
|
a nice ruby framework for us.
|
|
<br/>
|
|
Parslet lets us use modules for parts of the parser, so those files are pretty self-explanitory.
|
|
Not all is done, but a good start.
|
|
<br/>
|
|
Parslet also has a seperate Transformation pass, and that creates the AST. Those class names are also
|
|
easy, so you can guess what an IfExpression represents.
|
|
<br/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Virtual Machine</h5>
|
|
<p>
|
|
The Virtual machine layer is where it gets interesting, but also a little fuzzy.
|
|
<br/>
|
|
After some trying around the virtual machine layer has become a completely self contained layer to describe and
|
|
implement an oo machine. In other words it has no reference to any physical machine, that is the next layer down.
|
|
<br/>
|
|
One can get headaches quite easily while thinking about implementing an oo machine in oo, it's just so difficult to
|
|
find the boundaries. To determine those, i like to talk of types (not classes) for the objects (values) in which the
|
|
vm is implemented. Also it is neccessary to remove ambiguity about what message sending means.
|
|
<br/>
|
|
One way to think of this (helps to keep sane) is to think of the types of the system known at compile time. In the
|
|
simplest case this could be object reference and integer. The whole vm functionality can be made to work with only
|
|
those two types, and it is not specified how the type information is stored. but off course there needs to be a
|
|
way to check it at run-time.
|
|
<br/>
|
|
The vm has an instruction set that, apart from basic integer manipulation, only alows for memory access into an
|
|
object. Instead of an implicit stack, we use activation frames and store all variables explicitly.
|
|
</p>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Compilation in passes</h5>
|
|
<p>
|
|
Compilation happens in Passes. A single pass is a small piece of code to do just a very small part of the
|
|
whole compilation.
|
|
<br/>
|
|
Logically there are four distinct steps. From the parsed AST we compile a datastructure that includes instructions
|
|
for an object machine. The next step is a (still abstract) register machine, before the actual binary for the
|
|
arm is generated.
|
|
</p>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Register Machine</h5>
|
|
<p>
|
|
The Register machine layer is a relatively close abstraction of hardware.
|
|
<br/>
|
|
The step from OO machine to Arm had proved to large, also partially due to the cryptic arm names.
|
|
<br/>
|
|
The register machine has registers, indexed addressing, a pc and all the sort of normal things one would expect.
|
|
The machine has it's own (abstract) instruction set, which serves mainly to give understandable names.
|
|
<br/>
|
|
The mapping to arm is quite straightforward.
|
|
</p>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Parfait</h5>
|
|
<p>
|
|
Ruby is very dynamic, and so it has a relatively large run-time. Parfait is that Run-time.
|
|
<br/>
|
|
Parfait includes all the functionality a ruby program could not do without, Array, Hash, Object, Class, etc.
|
|
<br/>
|
|
Parfait does not include any stdlib or indeed core functionality if it doesn't have too.
|
|
<br/>
|
|
Parfait is coded in ruby, but not all functionality can be coded in ruby, so there is Builtin
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="span12">
|
|
<h5>Builtin</h5>
|
|
<p>
|
|
Builtin is the part of the vm that can not be coded in ruby. It is not, as may be imagined, a set of instructions,
|
|
but rather a set of modules.
|
|
<br/>
|
|
Modules of Builtin have functions that implement functionality that can not be coded in ruby. Ie array access.
|
|
The functions take a VM::Method and provide the code as a set of instructions. This may be seen as the assembler
|
|
layer if the vm.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|