我正在研究RubyVM的实现,并且我已经搜索了所有关于操作码的文档,但无济于事。
如果有人特别知道putspecialobject
操作码是如何工作的,或者甚至只是链接到一些完整的文档,我会非常感激!
答案 0 :(得分:4)
来自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
,这是在VM启动早期创建的对象,它将某些语言功能实现为方法:
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'传递给上述方法的类。
所以
def foo ... end
编译到:
[:putspecialobject, 1], [:putspecialobject, 2], [:putobject, :foo], [:putiseq, [...]], [:send, :"core#define_method", 3, nil, 0, nil]
这就像我可以进行逆向工程一样,这对于这段代码来说并不容易。