The Nara Virtual Machine
This document describes the Nara Virtual Machine (from now on naravm), in which Nara code runs.
A nara program is turned into a bytecode format by the Nara Compiler (narac). This bytecode
format is then run by naravm, to execute the program.
naravm is (to be) a register-based virtual machine.
Execution model
Opcodes
.op_ret
Returns the flow of execution. When ran inside a call frame, setups registers & returns flow control to the caller. When ran in the main function halts execution.
On-disk format
A nara program can be compiled and stored in disk, to a format that enables naravm to later
read & execute it. We refer to this format as a VM File or vmfile.
As of 2026-06-18, a vmfile contains all the data it needs to execute a single program. All values inside are stored as big-endian.
VM File Format
In the following section we use UX to denote the number of bytes in disk, where X can be
any number from 1 to 8. Therefore, U8 would refer to 8 bytes on disk. We also use Pad8,
which means "whatever number of bytes required to reach the next 8-byte boundary", and Pad4
for padding to the next 4 byte boundary.
A vmfile has the following format:
VmFile {
U4 magic,
U4 version,
ValueSection {
U4 padding,
U4 count,
[count]U8 values,
}
BlobSection {
U4 len,
[len]U1 bytes,
Pad4 padding,
}
ConstantsSection {
U4 count // how many constants are there in the table
[count]U1 constant_tags // tags of the constants
Pad4 padding
[count]Constant constants
}
Functions {
U4 count
[count]Function functions
}
}
Constant = union {
.Value {
@Tag = 0x01
U4 idx
}
.String {
@Tag = 0x02
U4 offset, // offset from the start of the Blob section
U4 len,
}
}
Function {
U4 name_pool_idx, // idx to a String in the constant pool
U4 bytecode_len,
[bytecode_len]U1 bytecode,
Pad4 padding,
}
- Bytecode
These are described as follows:
- magic: A magic string identifying the Nara bytecode file format. Its value is
0x6E617261, that is, the word"nara"encoded in ASCII. - version: A unsigned number signaling the version of this Nara bytecode file.
- Value section: contains all constant values used by the program, across all functions. These constants are then refererred to by index by entries in the constants pool.
- Constants pool: A ordered list of all constants used by this program. Each entry consists of a tag (1 byte) and a index (7 bytes). The tag determines on which section to look for.
- Bytecode: Raw bytes, interpreted as bytecode & executable by the machine.