|
| 1 | +# The Virtual Machine (vm.zig) |
| 2 | + |
| 3 | +This file comprises of the actual execution engine. It has 32 64bit registers (this is a limitation due to register ids can only be stored in 5 bits). All instructions are saved in 32 bits. It has a few advantages, as near jump instructions (all pc modifying I-type instructions) can actually address a 4095 other addresses (2047 back and 2046 front). |
| 4 | + |
| 5 | +All arithmetic is done on two's complement signed 64 bit integers if not stated otherwise. |
| 6 | + |
| 7 | +## Initialization |
| 8 | + |
| 9 | +The VM can be initialized in multiple ways. The standard way is to create a VM struct and then call the `.run()` function. It automatically initializes the virtual machine, and starts executing code. |
| 10 | + |
| 11 | +```zig |
| 12 | +var vm = VM{ |
| 13 | + .program = program[0..], |
| 14 | +}; |
| 15 | +
|
| 16 | +vm.run(event_allocator, page_allocator); |
| 17 | +
|
| 18 | +// at the end of this scope, deinitialize all the virtual machine's memory. |
| 19 | +defer vm.deinit(); |
| 20 | +``` |
| 21 | + |
| 22 | +The `.run()` function takes two allocators. These are responsible for the memory allocation of particular type (usually you can pass both the same allocator). The `event_allocator` is for the virtual machine events. These are messages that you can use to signal to the VM or the VM itself can use to signal to you. |
| 23 | + |
| 24 | +The `page_allocator` is used to allocate memory inside the virtual machine, the `gp` and `fp` instructions use it to create and free pages. You should use a high performing allocator, it can be beneficial to use the `c_allocator` even though it can produce leaked memory and must be handled with caution. |
| 25 | + |
| 26 | +The couple `.init()` and `.deinit()` are used to initialize and deinitialize structs inside the VM itself. It is a standard zig pattern. All heap allocated memory is freed in `.deinit()`. |
| 27 | + |
| 28 | +## Runtime |
| 29 | + |
| 30 | +`.next_instruction()` this function is a simple one. It returns the next instruction at position of the program counter (`pc`) and advances it by one. |
| 31 | + |
| 32 | +`.exec_instruction()` this function executes one instruction on the VM. It can halt the VM or it should continue. |
| 33 | + |
| 34 | +| returned value | meaning | |
| 35 | +| -------------- | ----------------------------------------------------------------------------------------- | |
| 36 | +| `VMError.*` | the VM encountered an error, you should handle it accordingly, the default is to halt | |
| 37 | +| `false` | the VM halted with the `HLT` instruction, the error code is written in the `VM.exit_code` | |
| 38 | +| `true` | the VM should continue it's execution | |
| 39 | + |
| 40 | +There are some at first glance weird methods (starting with the `@` symbol) but that's just a type casting that is quite strict in zig and is very well defined contrary to C for example. |
0 commit comments