1. Rubinius Bytecode Compiler

The Rubinius bytecode compiler converts Ruby source code to bytecode that the
virtual machine can execute.


2. Parser

The parser is a C extension named melbourne. It is basically the parser from
MRI wrapped up in a way that can be used in Rubinius. The parser converts Ruby
source code to an internal parse tree of nodes. The parse tree is processed by
calling a Ruby method for each node. The processor is in
lib/melbourne/processor.rb. The methods in the processor create Ruby objects
that are nodes in an abstract syntax tree (AST). The AST is processed to
generate bytecode.


3. Compiler

TODO: document the compiler.


4. Compiler Plugins

TODO: document the compiler plugin architecture.


4.1. Safe Math Compiler Plugin

Since the core libraries are built of the same blocks as any other Ruby code
and since Ruby is a dynamic language with open classes and late binding, it is
possible to change fundamental classes like Fixnum in ways that violate the
semantics that other classes depend on. For example, imagine we did the
following:

  class Fixnum
    def +(other)
      (self + other) % 5
    end
  end

While it is certainly possible to redefine fixed point arithmetic plus to be
modulo 5, doing so will certainly cause some class like Array to be unable to
calculate the correct length when it needs to. The dynamic nature of Ruby is
one of its cherished features but it is also truly a double-edged sword in
some respects.

In the standard library the 'mathn' library redefines Fixnum#/ in an unsafe
and incompatible manner. The library aliases Fixnum#/ to Fixnum#quo, which
returns a Float by default.

Because of this there is a special compiler plugin that emits a different
method name when it encounters the #/ method. The compiler emits #divide
instead of #/. The numeric classes Fixnum, Bignum, Float, and Numeric all
define this method.

The `-frbx-safe-math` switch is used during the compilation of the Core
libraries to enable the plugin. During regular 'user code' compilation, the
plugin is not enabled. This enables us to support mathn without breaking the
core libraries or forcing inconvenient practices.
