Closed
Description
Currently, the VM uses a simple dispatch loop, which boils down to:
match next_opcode() {
op::LoadReg => vm.op_load_reg(decode_args::<LoadReg>()),
op::StoreReg => vm.op_store_reg(decode_args::<StoreReg>()),
// ... etc.
}
It could be replaced by a less portable direct-threaded dispatch written in architecture-specific assembly for a few platforms (most likely only x86_64 and arm64), similar to this one (note that this code is heavily outdated, as it used the super unstable LLVM assembly macro, and asm
has since been stabilised). The concept boils down to:
// create a jump table where `jump_table[opcode]` is the label address of the dispatch handler for that opcode
let jump_table = [label_addr!("dispatch_load_reg"), label_addr!("dispatch_store_reg"), ...];
// setup `pc` and `op` registers, jump to the first instruction
trampoline!(vm, pc, op, jump_table);
// all opcodes would be defined similar to this:
dispatch_handler!(load_reg, (vm, pc, op, jump_table) {
// call VM's opcode handler
vm.op_load_reg(decode_args::<LoadReg>());
// load + dispatch next instruction
dispatch!(vm, pc, op, jump_table);
})
Metadata
Metadata
Assignees
Labels
No labels