How does the putspecialobject opcode work in RubyVM?
1 answer
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, then it is pushed on the stack rb_mRubyVMFrozenCore
, which is an object created at the start of 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 onto the stack. That the lexical scope in which constants and def
and are allowed alias
takes effect. It is also a class passed as "class" for the methods above.
So,
def foo ... end
compiles:
[: putspecialobject, 1], [: putspecialobject, 2], [: putobject,: foo], [: putiseq, [...]], [: send,: "core # define_method", 3, nil, 0, nil]
This is as much as I could redesign, which is not easy with this code.
+4
a source to share