Phasor 3.3.0
Stack VM based Programming Language
Loading...
Searching...
No Matches
VM.hpp
Go to the documentation of this file.
1#pragma once
3#ifndef CMAKE_PCH
4#include <Value.hpp>
5#endif
6#include <vector>
7#include <filesystem>
8#include <functional>
9#include <map>
10#include <array>
11#include <ranges>
12#include "core/core.h"
13#include <iostream>
14#include <stdexcept>
15#include <memory_resource>
16#ifdef TRACING
17#include <format>
18#include "../../ISA/map.hpp"
19#endif
20#include <platform.h>
21#include <version.h>
22#ifndef SANDBOXED
23#include "../FFI/ffi.hpp"
24#endif
25
27namespace Phasor
28{
29
32class VM
33{
34 public:
35 VM();
36 VM(const Bytecode &bytecode);
37 VM(const OpCode &op, const int &operand1 = 0, const int &operand2 = 0, const int &operand3 = 0);
38 ~VM();
39
41 void initFFI(const std::filesystem::path &path);
42
44 std::string getVersion();
45
48 class Halt : public std::exception
49 {
50 public:
51 const char *what() const noexcept override
52 {
53 return "";
54 }
55 };
56
59 int run(const Bytecode &bytecode, const size_t startPC = 0);
60
62 Value runFunction(const std::string &name, const Bytecode &bytecode);
63
65 using NativeFunction = std::function<Value(const std::vector<Value> &args, VM *vm)>;
66
68 void registerNativeFunction(const std::string &name, NativeFunction fn);
69
70 using ImportHandler = std::function<void(const std::filesystem::path &path)>;
72 void setImportHandler(const ImportHandler &handler);
73
75 void freeVariable(size_t index);
76
78 void freeVariableByName(const std::string &name);
79
83 size_t addVariable(const Value &value);
84
88 void setVariable(size_t index, const Value &value);
89
91 Value getVariable(size_t index);
92
94 size_t getVariableCount();
95
99 void setRegister(uint8_t index, const Value &value);
100
103 void freeRegister(uint8_t index);
104
108 Value getRegister(uint8_t index);
109
112 size_t getRegisterCount();
113
150
151#define REGISTER1 VM::Register::r0
152#define REGISTER2 VM::Register::r1
153#define REGISTER3 VM::Register::r2
154
155#ifdef _WIN32
157 Value __fastcall operation(const OpCode &op, const int &operand1 = 0, const int &operand2 = 0,
158 const int &operand3 = 0);
159#else
161 Value operation(const OpCode &op, const int &operand1 = 0, const int &operand2 = 0, const int &operand3 = 0);
162#endif
164 void push(const Value &value);
165
167 Value pop();
168
170 Value peek();
171
173 void cleanup();
174
176 void reset(const bool &resetStack = true, const bool &resetFunctions = true, const bool &resetVariables = true);
177
179 std::string getInformation();
180
182 std::string getBytecodeInformation();
183
185 void log(const Value &msg);
186
188 void logerr(const Value &msg);
189
191 void flush();
192
194 void flusherr();
195
197 void setStatus(int newStatus);
198 void resetStatus();
199 int getStatus();
200
208 template <typename... Args> inline Value regRun(OpCode opcode, Args &&...args)
209 {
210 int regIndex = 0;
211 (setRegister(regIndex++, std::forward<Args>(args)), ...);
212 operation(opcode);
213 return getRegister(REGISTER1);
214 }
215
223 template <typename... Args> inline Value stackRun(OpCode opcode, Args &&...args)
224 {
225 Value arr[] = {Value(std::forward<Args>(args))...};
226 for (Value &v : arr | std::views::reverse)
227 push(v);
228 operation(opcode);
229 return pop();
230 }
231
232 private:
233 void setup(const Bytecode &bc, const size_t initialPC);
234 void evalLoop();
235
236 bool isDirectCall = false;
237
238#ifndef SANDBOXED
240 std::unique_ptr<FFI> ffi;
241#endif
243 int status = 0;
244
247
249 std::array<Value, MAX_REGISTERS> registers;
250
252 std::pmr::monotonic_buffer_resource stack_pool;
253 std::pmr::vector<Value> stack;
254
256 std::vector<int> callStack;
257
259 std::vector<Value> variables;
260
263
265 size_t pc = 0;
266
268 std::map<std::string, NativeFunction> nativeFunctions;
269};
270} // namespace Phasor
#define msg
#define REGISTER1
Definition VM.hpp:151
Expanded opcode set for Phasor VM.
Throws when the HALT opcode is reached.
Definition VM.hpp:49
const char * what() const noexcept override
Definition VM.hpp:51
std::array< Value, MAX_REGISTERS > registers
Virtual registers for register-based operations (v2.0).
Definition VM.hpp:249
ImportHandler importHandler
Import handler for loading modules.
Definition VM.hpp:246
Value operation(const OpCode &op, const int &operand1=0, const int &operand2=0, const int &operand3=0)
Execute a single operation.
Definition Operations.cpp:8
std::vector< Value > variables
Variable storage indexed by variable index, or simply: the managed heap.
Definition VM.hpp:259
std::function< Value(const std::vector< Value > &args, VM *vm)> NativeFunction
Native function signature.
Definition VM.hpp:65
Value pop()
Pop a value from the stack.
Definition Stack.cpp:17
void setImportHandler(const ImportHandler &handler)
Set the import handler for importing modules.
Definition Utility.cpp:153
VM()
Definition VM.cpp:8
std::function< void(const std::filesystem::path &path)> ImportHandler
Definition VM.hpp:70
void logerr(const Value &msg)
Log a Value to stderr.
Definition Utility.cpp:275
std::string getVersion()
Get Phasor VM version.
Definition Utility.cpp:34
void evalLoop()
Definition Utility.cpp:73
std::unique_ptr< FFI > ffi
FFI.
Definition VM.hpp:240
bool isDirectCall
is a direct call to a function
Definition VM.hpp:236
Value getVariable(size_t index)
Get a variable from the VM.
Definition Variables.cpp:58
void registerNativeFunction(const std::string &name, NativeFunction fn)
Register a native function.
Definition Native.cpp:5
Value getRegister(uint8_t index)
Get a register value.
Definition Register.cpp:26
void setStatus(int newStatus)
Set VM exit code.
Definition Utility.cpp:38
void freeVariableByName(const std::string &name)
Free a variable by name in the VM.
Definition Variables.cpp:30
size_t getVariableCount()
Get the number of variables in the VM.
Definition Variables.cpp:75
std::vector< int > callStack
Call stack for function calls.
Definition VM.hpp:256
std::string getBytecodeInformation()
Get bytecode information for debugging.
Definition Utility.cpp:234
void log(const Value &msg)
Log a Value to stdout.
Definition Utility.cpp:269
size_t addVariable(const Value &value)
Add a variable to the VM.
Definition Variables.cpp:8
int getStatus()
Definition Utility.cpp:46
~VM()
Definition VM.cpp:37
void flush()
Flush stdout.
Definition Utility.cpp:281
std::pmr::vector< Value > stack
Definition VM.hpp:253
void cleanup()
Clean up the virtual machine.
Definition Utility.cpp:162
Register
Enum for registers.
Definition VM.hpp:116
size_t pc
Program counter.
Definition VM.hpp:265
void push(const Value &value)
Push a value onto the stack.
Definition Stack.cpp:8
Value stackRun(OpCode opcode, Args &&...args)
Run an opcode with values pushed to the stack.
Definition VM.hpp:223
void resetStatus()
Definition Utility.cpp:42
void setVariable(size_t index, const Value &value)
Set a variable in the VM.
Definition Variables.cpp:45
int run(const Bytecode &bytecode, const size_t startPC=0)
Run the virtual machine Exits -1 on uncaught exception.
Definition Utility.cpp:88
void initFFI(const std::filesystem::path &path)
Initialize the FFI plugins.
Definition Utility.cpp:51
void setRegister(uint8_t index, const Value &value)
Set a register value.
Definition Register.cpp:8
std::map< std::string, NativeFunction > nativeFunctions
Native function registry.
Definition VM.hpp:268
Value runFunction(const std::string &name, const Bytecode &bytecode)
Run a function from bytecode on the virtual machine.
Definition Utility.cpp:144
void freeRegister(uint8_t index)
Free a register (reset to null).
Definition Register.cpp:17
const Bytecode * m_bytecode
Bytecode to execute.
Definition VM.hpp:262
void setup(const Bytecode &bc, const size_t initialPC)
Definition Utility.cpp:58
std::pmr::monotonic_buffer_resource stack_pool
Stack.
Definition VM.hpp:252
int status
Exit code.
Definition VM.hpp:243
Value regRun(OpCode opcode, Args &&...args)
Run an opcode with arguments pre-loaded into registers.
Definition VM.hpp:208
Value peek()
Peek at the top value on the stack.
Definition Stack.cpp:38
void flusherr()
Flush stderr.
Definition Utility.cpp:286
size_t getRegisterCount()
Get the total number of registers.
Definition Register.cpp:35
void reset(const bool &resetStack=true, const bool &resetFunctions=true, const bool &resetVariables=true)
Reset the virtual machine.
Definition Utility.cpp:181
void freeVariable(size_t index)
Free a variable in the VM.
Definition Variables.cpp:18
std::string getInformation()
Get VM information for debugging.
Definition Utility.cpp:207
A value in the Phasor VM.
Definition Value.hpp:58
The Phasor Programming Language and Runtime.
Definition AST.hpp:12
OpCode
Definition ISA.hpp:12
Complete bytecode structure.
Definition CodeGen.hpp:50