anchor.diff: -# 1.0 Introduction
  += Iridium VM Specification
  +:toc:
  +:author: Fletcher Haynes
  +:email: fletcher@subnetzero.io
  +
  +== 1.0 Introduction
   Hi there! This document contains the formal specification for the Iridium VM; it should be considered authoritative.
   
  -## 1.1 An Overview of the VM
  +=== 1.1 An Overview of the VM
   The *Iridium VM* project provides a platform for writing, deploying, and managing applications that are extremely resilient and low-latency. In terms of discrete components, the three main logical components are:
   
   1. A language VM that executes Iridium-specific bytecode
  
positive.code: 
  This is not to say that these goals are incompatible, but it is helpful to general establish priorities.
  
  ## 1.2 Similar Work
  There are only two similar platforms I know of that have done something similar. I'm not going to detail all their features here.
  
  ### BEAM VM
  This is the Erlang VM. It, and the Erlang OTP library, have served as a heavy source of inspiration for this project.
  
  ### Lua
  Later versions of Lua use a register-based virtual machine. There is also a project, LuaJIT, that showcases what a good JIT can do.
  
  ## 1.3 Feedback
  You can join any of our various chat mediums, or e-mail iridium@subnetzero.io.
  
  # 2.0 Iridium VM Specification
  This covers the internals of the Iridium VM. Number and type of registers, opcodes, instructions, etc.
  
  ## 2.1 Registers
  Iridium is a _register-based_ virtual machine. Details are:
  
  1. It has 32 registers capable of holding one i32 number
  2. Registers are numbered 0-31
  3. All registers are general-purpose registers
  
  ## 2.2 Program Counter
  The VM data structure has a Rust `usize` variable that tracks the current byte evaluated by the VM. This is the `pc`, or the `Program Counter`.
  
  ## 2.3 Special-purpose Registers
  The VM data structure has attributes that take the place of special-purpose registers:
  
  .Special register types
  
negative.code: 
  Opcodes know how and when to access these fields.
  
  === 2.4 Bytecode
  At the lowest level, bytecode is stored in a `Vector` of `u8s`. The previously mentioned program counter tracks the index into that vector.
  
  Bytecode is generated by the assembler component, which is covered in a different document.
  
  === 2.5 Bytecode Header
  After assembly, the output is a file containing a lot of 1s and 0s. The first 64 bytes are the `Header` for an Iridium bytecode file. The Linux `ELF` format operates in a similar way.
  
  As with `ELF`, the first four bytes of the header are a "magic number": `[45, 50, 49, 45]`. For the curious, this spells out `EPIE` in ASCII.
  
  Bytes 5-64 are not used and are reserved for future use.
  
  === 2.5 Read-Only Section
  After the header comes the read-only data section of the bytecode. This stores constants found by the assembler.
  
  In the VM data structure, this section is a `Vector` of `u8s` and may be of arbitrary length.
  
  The offset at which the read-only section _ends_ is encoded in the first four bytes after the header. So bytes 65-69. All bytes after that are executable bytecode.
  
  === 2.6 Heap Memory
  When values cannot be stored in registers, they can be moved to the `Heap`. In the VM, the heap is represented as, you guessed it, a `Vector` of `u8s`. At startup, the VM pre-allocates 2048 bytes and will expand it as needed.
  
  === 2.7 Instruction Width
  Iridium VM uses a fixed-bit instruction format. Iridium expects that each instruction is 32-bits wide. Each iteration of the execution loop will consume 32 bits. Some of the opcodes do not need all 32-bits; those are padded by the assembler.
  
  == 3.0 Opcodes
  The first byte of a 4-byte wide instruction is the Opcode. The following Opcodes are supported:
  
  .Opcodes
  