Search code examples
rubyopcodevm-implementation

How does the putspecialobject opcode in the RubyVM work?


I'm working on an implementation of the RubyVM and I've searched all over for some documentation on the opcodes, but to no avail.

If anyone knows specifically how the putspecialobject opcode works, or even just a link to some fullish documentation I'd much appreciate it!


Solution

  • From insns.def:

    DEFINE_INSN putspecialobject (rb_num_t value_type) () (VALUE val)
    {
      switch (value_type) {
        case VM_SPECIAL_OBJECT_VMCORE:
          val = rb_mRubyVMFrozenCore;
          break;
        case VM_SPECIAL_OBJECT_CBASE:
          val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
          break;
        default:
          rb_bug("putspecialobject insn: unknown value_type");
      }
    }
    

    where:

    VM_SPECIAL_OBJECT_VMCORE = 1
    VM_SPECIAL_OBJECT_CBASE  = 2
    

    In other words, if the argument is 1, rb_mRubyVMFrozenCore is pushed on the stack, which is an object created early in VM startup that implements some language features as methods:

    set_method_alias(klass,:new,:old)             alias new old
    set_variable_alias(:$new,:$old)               alias $new $old
    undef_method(klass,:foo)                      undef foo
    define_method(klass,:foo,&block)              def foo ... end
    define_singleton_method(obj,:foo,&block)      def obj.foo ... end
    set_postexe(&block)                           END { ... }
    

    If the argument is 2, the class/module for the current class context is pushed on the stack. That's the lexical scope in which constants are resolved and def and alias take effect. It's also the class passed as 'klass' to the methods above.

    So

    def foo
      ...
    end
    

    compiles to this:

    [:putspecialobject, 1],
    [:putspecialobject, 2],
    [:putobject, :foo],
    [:putiseq, [...]],
    [:send, :"core#define_method", 3, nil, 0, nil]
    

    This is as much as I could reverse engineer, which isn't easy with this code.