Devoxx Greece 2024 - Busy Developer's Guide to Building a Bytecode Virtual Machine by Ted Neward

A guide to building a bytecode virtual machine, covering design patterns, bytecode instructions, and debugging techniques for developers.

Key takeaways
  • Virtual machines operate in similar ways, with a focus on fetching, decoding, and executing bytecode.
  • The JVM and CLR are examples of stack-based virtual machines.
  • Virtual machines can be built using native instructions, but this can be difficult to implement.
  • The no op instruction is useful for placeholder purposes.
  • The constant pool is important for storing constant values.
  • Virtual machines can use native calls to load and execute native code.
  • The JVM’s bytecode instructions include load, store, push, pop, and multiply.
  • The debugger can be used to examine bytecode and potentially change it at runtime.
  • Virtual machines can have their own internal representations of data and provide extensibility points.
  • Call frames and execution stacks are important for evaluating the state of a virtual machine.
  • Debugging tools can be used to examine the bytecode and internal state of a virtual machine.
  • Building a virtual machine can be complex, but it is also a fun and educational experience.
  • Virtual machines can be used to implement languages such as Java, Python, and JavaScript.
  • The JVM’s bytecode is typically executed in a fetch decode execute cycle.
  • Virtual machines can be deterministic or non-deterministic, depending on the implementation.
  • The heap is used for dynamic allocation in virtual machines.
  • Virtual machines can have implicit state, which can be accessed through the debugger.
  • Game engines and other applications can be built on top of virtual machines.
  • Virtual machines can be easy to implement for small languages, but more complex for larger languages.
  • The JVM’s call stack is used for evaluating method calls and procedure calls.
  • The JVM’s debugging tools allow for tracing and stepping through bytecode at runtime.
  • Virtual machines can be built to be efficient and performant, but also require manual tuning.
  • The JVM’s bytecode is designed to be platform-independent and can be executed on multiple platforms.
  • Virtual machines can be used to implement languages such as C, C++, and Python.