Programs written for Viua VM are modelled as sets of actors. Actors are concurrently executing processes completely isolated from each other, communicating only via asynchronous message passing.

Internally, each actor is executing sequentially as a sequence of function calls. An actor finishes execution when the call frame at the bottom of its call stack is popped (i.e. when the main function of the actor finishes execution). A function is a sequence of instructions manipulating values placed in registers.

If we consider:

- contents of registers available to an instruction
- the queue of messages waiting to be received by the process
- the instruction pointer of the process

```
An instruction is the most basic operation that can be executed
by the virtual machine. An instruction reads its inputs from the
state of an actor, executes an operation, and writes its outputs
to the state of the actor:
```*Fn : (State) -> State*

A *register* is a slot that is capable of holding any
value that may be represented by a Viua VM program.
A *register set* is a collection of registers with
a common lifetime.

There are three general purpose register sets:

- local
- static
- global

- arguments
- parameters

To access a value contained in a register the register must
be addressed, and an access type specifier must be given.
The syntax is simple: first the access type specifier is
given to inform the assembler how the value will be
accessed, then the register index is given, and then the
register set.

A few examples:

`%1 local`

: access a value in 1st register from local register set`*1 local`

: access a value to which the pointer in 1st register from local register set points`%2 static`

: access a value in 2nd register from static register set

Direct access may be used in both output, input, and mutable operands. It yields a value contained in the addressed register.

Pointer-dereference access may only be used in input and mutable operands; it is illegal to use pointer-dereference access in output operands. It yields a value to which the pointer contained in the addressed register points.

There are three kinds of operands that use register addresses:

- input operands
- output operands
- mutable operands

**Input** operands provide values for an
instruction to work on. An example of an input operand is
the second of third operand of the
`add`

instruction.

**Output** operands provide the instruction
with slots to save the result of its work.

If an operand provides the input for an instruction, but is
not only read by also changed by the instruction while it
executes it could be considered *both* an input and
an output operand. To simplify the nomenclature such
operands are called **mutable**.

There are 144 opcodes in 29 groups.

(sorted alphabetically)

- arithmetic (41 ops)
- atoms (2 ops)
- bits (56 ops)
- blocks (2 ops)
- calls (6 ops)
- checked_arithmetic (12 ops)
- closures (4 ops)
- concurrency (6 ops)
- control_flow (6 ops)
- ctor (21 ops)
- deprecated (2 ops)
- dtor (1 ops)
- error_handling (3 ops)
- exceptions (6 ops)
- float (1 ops)
- integer (1 ops)
- io (5 ops)
- logic (8 ops)
- misc (5 ops)
- pointers (2 ops)
- register_manipulation (6 ops)
- saturating_arithmetic (12 ops)
- strings (2 ops)
- structs (5 ops)
- text (8 ops)
- timed (3 ops)
- value_manipulation (4 ops)
- vectors (6 ops)
- wrapping_arithmetic (6 ops)

(sorted alphabetically)

- add — add two numbers and produce a number
- allocate_registers — allocate registers inside a call frame
- and — perform a boolean conjunction
- ashl — perform arithmetic left shift
- ashr — perform arithmetic right shift
- atom — construct an atom value
- atomeq — check two atom values for equality
- bitaeq — compare two bits values for equality treating them as unsigned integers
- bitagt — compare two bits values treating them as unsigned integers
- bitagte — compare two bits values treating them as unsigned integers
- bitalt — compare two bits values treating them as unsigned integers
- bitalte — compare two bits values treating them as unsigned integers
- bitand — perform a conjunction on two bits values
- bitat — obtain a value of a single bit in a bits value
- bitnot — perform a negation on a bits value
- bitor — perform a disjunction on two bits values
- bits — construct a bits value
- bits_of_integer — convert an integer value to a bits value
- bitseq — check two bits values for equality treating them as signed integers
- bitset — set a single bit in a bits value
- bitsgt — compare two bits values treating them as signed integers
- bitsgte — compare two bits values treating them as signed integers
- bitslt — compare two bits values treating them as signed integers
- bitslte — compare two bits values treating them as signed integers
- bitswidth — obtain the width of a bits value
- bitxor — perform a binary XOR operation on two bits values
- bool — construct a boolean value
- call — invoke a callable value (make a function or a closure call)
- capture — capture a value inside a closure by reference
- capturecopy — capture a value inside a closure by copy
- capturemove — capture a value inside a closure by move
- catch — catch an exception and transfer execution to a handling block
- checkedsadd — perform checked addition of two bits values treating them as signed integers
- checkedsdecrement — perform checked decrementation of a bits value treating it as a signed integer
- checkedsdiv — perform checked division of two bits values treating them as signed integers
- checkedsincrement — perform checked incrementation of a bits value treating it as a signed integer
- checkedsmul — perform checked multiplication of two bits values treating them as signed integers
- checkedssub — perform checked subtraction of two bits values treating them as signed integers
- checkeduadd — perform checked addition of two bits values treating them as unsigned integers
- checkedudecrement — perform checked decrement of a bits value treating it as an unsigned integer
- checkedudiv — perform checked division of two bits values treating them as unsigned integers
- checkeduincrement — perform checked increment of a bits value treating it as an unsigned integer
- checkedumul — perform checked multiplication of two bits values treating them as unsigned integers
- checkedusub — perform checked subtraction of two bits values treating them as unsigned integers
- closure — construct a closure value
- copy — copy a value from one register to another
- defer — schedule a deferred call
- delete — destroy a value
- div — divide two numbers and produce a number
- draw — draw a caught value into a register
- echo — print a value to standard output without adding a newline at the end
- enter — enter a block
- eq — check two numbers for equality
- float — construct a floating point value
- frame — create a call frame
- ftoi — convert an integer value to float value
- function — construct a function value
- gt — compare two numbers
- gte — compare two numbers
- halt — immediately halts current execution stack
- idec — decrement an integer
- if — perform a conditional jump
- iinc — decrement an integer
- import — dynamically import a module
- integer — construct an integer value
- integer_of_bits — convert a bits value to an integer value
- io_cancel — cancel an I/O request
- io_close — close an I/O port
- io_read — issue a read I/O request
- io_wait — wait for an I/O request to complete
- io_write — issue a write I/O request
- isnull — check if a register is empty
- itof — convert an integer value to a floating point value
- izero — construct an integer zero value
- join — wait for another process to complete
- jump — transfer execution to an instruction in the current block
- leave — leave a block
- lt — compare two numbers
- lte — compare two numbers
- move — move a value from one register to another
- mul — multiply two numbers
- nop — do nothing
- not — perform a boolean negation
- or — perform a boolean disjunction
- pideq — check two PID values for equality
- print — print a value to standard output adding a newline at the end
- process — create a new process
- ptr — construct a pointer to a value
- ptrlive — check if pointer is still live
- receive — receive a message
- return — return from a function call
- rol — perform bitwise left rotation
- ror — perform bitwise right rotation
- saturatingsadd — perform saturating addition of two bits values treating them as signed integers
- saturatingsdecrement — perform saturating decrement of a bits value treating it as a signed integer
- saturatingsdiv — perform saturating division of two bits values treating them as signed integers
- saturatingsincrement — perform saturating increment of a bits value treating it as a signed integer
- saturatingsmul — perform saturating multiplication of two bits values treating them as signed integers
- saturatingssub — perform saturating subtraction of two bits values treating them as signed integers
- saturatinguadd — perform saturating addition of two bits values treating them as unsigned integers
- saturatingudecrement — perform saturating decrement of a bits value treating it as a unsigned integer
- saturatingudiv — perform saturating division of two bits values treating them as unsigned integers
- saturatinguincrement — perform saturating increment of a bits value treating it as a unsigned integer
- saturatingumul — perform saturating multiplication of two bits values treating them as unsigned integers
- saturatingusub — perform saturating subtraction of two bits values treating them as unsigned integers
- self — construct a PID of the current process
- send — send a message to a process
- shl — perform bitwise left shift
- shr — perform bitwise right shift
- stof — convert a string value to a floating point value
- stoi — convert a string value to an integer value
- streq — check two string values for equality
- string — construct a string value
- struct — construct a struct value
- structat — access a struct field
- structinsert — insert a field into a struct, or overwrite an existing field
- structkeys — construct a vector of keys contained in a struct
- structremove — remove a field from a struct
- sub — subtract two numbers
- swap — swap values in two registers
- tailcall — make a tail call
- text — construct a text value
- textat — access a codepoint in a text value
- textcommonprefix — determine a common prefix of two text values
- textcommonsuffix — determine a common suffix of two text values
- textconcat — concatenate two text values
- texteq — check two text values for equality
- textlength — determine length of a text value
- textsub — extract a subtext from a text value
- throw — throw a value as an exception
- try — create a try frame for exception handling
- vat — access a value at a given index inside a vector value
- vector — construct a vector value
- vinsert — insert a value into a vector value at a given index
- vlen — determine length of a vector value
- vpop — pop a given index from a vector value
- vpush — push a value to a vector value
- watchdog — set a watchdog function for a process
- wrapadd — perform wrapping addition of two bits values treating them as signed integers
- wrapdecrement — perform wrapping decrement of a bits value treating it as a unsigned integer
- wrapdiv — perform wrapping division of two bits values treating them as signed integers
- wrapincrement — perform wrapping increment of a bits value treating it as a unsigned integer
- wrapmul — perform wrapping multiplication of two bits values treating them as signed integers
- wrapsub — perform wrapping subtraction of two bits values treating them as signed integers