本项目是一个简单的、图灵完备的脚本虚拟机,可以执行一个特定的指令集 .它有如下几个特性:
- 支持常量池
- 支持调用外部函数
- 支持指令级别直接读写内存
- 支持单步执行
- 支持Stacktrace
- 虚拟机运行于单独线程,但在销毁时会等待程序执行完毕
也有如下缺点:
- 未实现内建浮点数运算
- 未作任何优化
- 未实现字节码解析
- 未实现断点(简单,就不写了)
#include <hevm.hh>
void he_puts(HeVM::VirtualMachine &vm){
if(vm.stack.empty()){
vm.crash("Function he_puts: invalid arguments, stack is empty!");
}
int64_t offset = vm.stack.top(); vm.stack.pop();
puts((const char*)vm.constant_pool.data() + offset);
}
int main(){
std::vector<HeVM::Instruction> program = {
{HeVM::PUSH, 0, 0, 5},
{HeVM::LOAD_VAL, 1, 0, 0},
{HeVM::CALL_EXT, 1, 0, 0}
};
const char data[] = "puts\0Hello World!";
std::vector<uint8_t> constants = { data, data + sizeof(data)};
auto vm = HeVM::CreateVirtualMachine(program, constants);
vm->bind_function("puts", he_puts);
vm->run();
return 0;
}
运行结果:
新建一个CMake项目(建议使用Clion或者 Visual Studio 2019以上版本)。
将本项目clone至HeVM目录,在项目的CMakeLists.txt
文件中添加如下内容:
add_subdirectory(HeVM)
target_link_libraries(你的target名 PUBLIC HeVM)
在你的C++源代码中加入如下内容:
#include <hevm.hh>
在你需要创建虚拟机的地方使用如下代码:
auto vm = HeVM::CreateVirtualMachine(program, constants); // 创建一个虚拟机实例
namespace HeVM{
/**
* @brief 创建一个虚拟机实例
* @param programs 由指令四元组构成的程序
* @param constant_pool 程序的常量池
* @return 虚拟机实例
*/
std::unique_ptr<VirtualMachine>
CreateVirtualMachine(const std::vector<Instruction> &programs, const std::vector<uint8_t> &constant_pool);
};
/**
* @brief 开始执行虚拟机
*/
void VirtualMachine::run();
/**
* @brief 单步执行虚拟机
*/
void VirtualMachine::step();
/**
* @brief 暂停虚拟机, 可用于主动销毁虚拟机时防止阻塞
*/
void VirtualMachine::pause();
/**
* @brief 使虚拟机崩溃
* @param reason 崩溃说明
*/
void crash(const std::string &reason);
/*
* 绑定函数的原型
*/
using ExternalFunction = std::function< void(VirtualMachine& vm)>;
/**
* @brief 绑定外部函数,供CALL_EXT指令调用
* @param name 函数名称
* @param function 绑定到的函数
*/
void VirtualMachine::bind_function(const std::string& name, ExternalFunction function);
Example:
/**
* @param vm 虚拟机对象,如需要传参,请从vm.stack中获取
*/
void fun(HeVM::VirtualMachine& vm){
}