Из 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");
}
}
где:
VM_SPECIAL_OBJECT_VMCORE = 1
VM_SPECIAL_OBJECT_CBASE = 2
Другими словами, если аргумент равен 1, rb_mRubyVMFrozenCore
помещается в стек, который является объектом, созданным на раннем этапе запуска виртуальной машины, который реализует некоторые языковые функции в виде методов:
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 { ... }
Если аргумент равен 2, класс / модуль для текущего контекста класса помещается в стек. Это лексическая область, в которой константы разрешаются и действуют def
и alias
. Это также класс, переданный как 'klass' в методы выше.
So
def foo
...
end
компилируется в это:
[:putspecialobject, 1],
[:putspecialobject, 2],
[:putobject, :foo],
[:putiseq, [...]],
[:send, :"core#define_method", 3, nil, 0, nil]
Это столько, сколько я мог бы перепроектировать, что нелегко с этим кодом.