Как работает код операции putspecialobject в RubyVM?
-
23-08-2019 - |
Вопрос
Я работаю над реализацией RubyVM и искал всю документацию по кодам операций, но безуспешно.
Если кто-нибудь знает конкретно, как putspecialobject
код операции работает, или даже просто ссылку на какую-нибудь полную документацию, я был бы очень признателен!
Решение
Из 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
вступить в силу.Это также класс, передаваемый как «класс» вышеприведенным методам.
Так
def foo ... end
компилируется так:
[:putspecialobject, 1], [:putspecialobject, 2], [:putobject, :foo], [:putiseq, [...]], [:send, :"core#define_method", 3, nil, 0, nil]
Это все, что я смог перепроектировать, что непросто с этим кодом.