17inline bool isDebuggerAttached()
19 return IsDebuggerPresent() == TRUE;
23#include <sys/ptrace.h>
24inline bool isDebuggerAttached()
26 return ptrace(PTRACE_TRACEME, 0, 1, 0) == -1;
36 return PHASOR_VERSION_STRING;
54 ffi = std::make_unique<FFI>(path,
this);
80 log(std::format(
"\nVM::{}(): RUN (pc={})\n", __func__,
pc - 1));
93 log(std::format(
"\nVM::{}():\n\n", __func__));
98 using clock = std::chrono::high_resolution_clock;
99 auto start = clock::now();
110 auto end = clock::now();
111 auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
112 log(std::format(
"VM::{}(): Duration of bytecode execution: {}us\n\n", __func__, us));
120 if (isDebuggerAttached())
125#if defined(TRACING) || defined(_DEBUG)
126 catch (
const std::exception &e)
128 catch (
const std::exception &)
132 logerr(std::format(
"\nVM::{}(): UNCAUGHT EXCEPTION!\n\n{}\n{}\n\n", __func__, e.what(),
getInformation()));
137 logerr(std::format(
"{}\n", e.what()));
149 reset(
true,
false,
true);
156 log(std::format(
"VM::{}()\n", __func__));
165 log(std::format(
"VM::{}()\n", __func__));
178 reset(
true,
true,
true);
181void VM::reset(
const bool &resetStack,
const bool &resetFunctions,
const bool &resetVariables)
184 log(std::format(
"VM::{}()\n", __func__));
214 info = std::format(
"Stack Top: {:T}\n",
peek());
217 std::string registersStr;
224 registersStr += std::format(
"R{}: {:T}\n", regCount, reg);
229 info += std::format(
"VM INFORMATION:\n{}PC: {}\nCS: {}", registersStr,
pc, callStackTop);
237 std::string constants;
239 std::string functions;
240 std::string instructions;
242 for (
const auto &constant :
m_bytecode->constants)
244 constants += std::format(
"{:T}\n", constant);
246 for (
const auto &variable :
m_bytecode->variables)
248 variables += std::format(
"{}\n", variable.first);
250 for (
const auto &function :
m_bytecode->functionEntries)
252 functions += std::format(
"{}() PC = {}\n", function.first, function.second);
255 for (
const auto &instruction :
m_bytecode->instructions)
257 instructions += std::format(
"{}({}, {}, {})\n",
opCodeToString(instruction.op), instruction.operand1,
258 instruction.operand2, instruction.operand3);
263 "BYTECODE INFORMATION:\n\nConstants: {}\n{}\nVariables: {}\n{}\nFunctions: {}\n{}\nInstructions: {}\n{}",
271 std::string
s =
msg.toString();
277 std::string
s =
msg.toString();
void c_print_stderr(const char *s, int64_t len)
Native print error function.
void c_print_stdout(const char *s, int64_t len)
Native print function.
Throws when the HALT opcode is reached.
std::array< Value, MAX_REGISTERS > registers
Virtual registers for register-based operations (v2.0).
ImportHandler importHandler
Import handler for loading modules.
Value operation(const OpCode &op, const int &operand1=0, const int &operand2=0, const int &operand3=0)
Execute a single operation.
std::vector< Value > variables
Variable storage indexed by variable index, or simply: the managed heap.
Value pop()
Pop a value from the stack.
void setImportHandler(const ImportHandler &handler)
Set the import handler for importing modules.
std::function< void(const std::filesystem::path &path)> ImportHandler
void logerr(const Value &msg)
Log a Value to stderr.
std::string getVersion()
Get Phasor VM version.
std::unique_ptr< FFI > ffi
FFI.
bool isDirectCall
is a direct call to a function
void setStatus(int newStatus)
Set VM exit code.
std::vector< int > callStack
Call stack for function calls.
std::string getBytecodeInformation()
Get bytecode information for debugging.
void log(const Value &msg)
Log a Value to stdout.
void flush()
Flush stdout.
std::pmr::vector< Value > stack
void cleanup()
Clean up the virtual machine.
size_t pc
Program counter.
int run(const Bytecode &bytecode, const size_t startPC=0)
Run the virtual machine Exits -1 on uncaught exception.
void initFFI(const std::filesystem::path &path)
Initialize the FFI plugins.
std::map< std::string, NativeFunction > nativeFunctions
Native function registry.
Value runFunction(const std::string &name, const Bytecode &bytecode)
Run a function from bytecode on the virtual machine.
const Bytecode * m_bytecode
Bytecode to execute.
void setup(const Bytecode &bc, const size_t initialPC)
std::pmr::monotonic_buffer_resource stack_pool
Stack.
Value peek()
Peek at the top value on the stack.
void flusherr()
Flush stderr.
void reset(const bool &resetStack=true, const bool &resetFunctions=true, const bool &resetVariables=true)
Reset the virtual machine.
std::string getInformation()
Get VM information for debugging.
A value in the Phasor VM.
The Phasor Programming Language and Runtime.
std::string opCodeToString(OpCode op)
Complete bytecode structure.
std::unordered_map< std::string, int > functionEntries
Function name -> instruction index mapping.
Instruction with up to 5 operands Format: instruction operand1, operand2, operand3 Each instruction u...
int32_t operand1
First operand.
int32_t operand2
Second operand.
int32_t operand3
Third operand.