Advent of YARV: Part 24 - Wrap up

This blog series is about how the CRuby virtual machine works. If you’re new to the series, I recommend starting from the beginning. This is the last post in the series.

At this point, we’ve actually covered every instruction in the YARV instruction set that gets compiled in by default. There are four instructions, however, that can be optionally compiled in. This last post will cover those instructions.


Back in 2007, the opt_call_c_function instruction was introduced. By default this isn’t compiled into the Ruby binary, but you can turn it on by defining SUPPORT_CALL_C_FUNCTION. It has a single operand which is a function pointer to a C function. The function should accept a pointer to the execution context and a pointer to the current frame and return a pointer to a control frame. In C, this would look like:

typedef rb_control_frame_t *
  (*rb_insn_func_t)(rb_execution_context_t *, rb_control_frame_t *);

This instruction can do literally anything it wants to the state of the virtual machine, and as such is both enormously powerful and dangerous.


The reput instruction is used when OPT_STACK_CACHING is defined. The usage of stack caching is entirely out of scope of this blog series, but the reput instruction itself at the moment does nothing. If you want to read more about stack caching or see it in action, here are a couple of links:


The answer instruction is used when OPT_SUPPORT_JOKE is defined. It’s a simple instruction that pushes the answer to life, the universe, and everything onto the stack. That is to say, it pushes the integer 42 onto the stack. This instruction will get compiled into the instruction sequence if the compiler finds a method call to the_answer_to_life_the_universe_and_everything without an explicit receiver.


The bitblt instruction is also used when OPT_SUPPORT_JOKE is defined. It’s another simple instruction that pushes a string onto the stack. The string is "a bit of bacon, lettuce and tomato". This instruction will get compiled into the instruction sequence if the compiler finds a method call to bitblt without an explicit receiver.

Wrapping up

That’s it! That’s the entire blog series. I hope you enjoyed it and learned as much as I did. Below are some things that we learned in this series that I think are worth highlighting:

Now here are a couple of things that we didn’t cover in this series. I think it’s important to point these things out so that you know what you’re missing, but also what you can look up next:

Thank you so very much for reading. I was very excited to share this information with you. I hope you have a very happy holiday season and new year. If you have any feedback or just want to say hi, feel free to drop me a line on Twitter.

← Back to home