我正在研究 RubyVM 的实现,并且我到处搜索有关操作码的一些文档,但无济于事。
如果有人具体知道putspecialobject
操作码是如何工作的,或者只是一个指向一些完整文档的链接,我将不胜感激!
我正在研究 RubyVM 的实现,并且我到处搜索有关操作码的一些文档,但无济于事。
如果有人具体知道putspecialobject
操作码是如何工作的,或者只是一个指向一些完整文档的链接,我将不胜感激!
来自 insns.def:
DEFINE_INSN putspecialobject (rb_num_t value_type) () (VALUE val) { 开关(值类型){ 案例 VM_SPECIAL_OBJECT_VMCORE: val = rb_mRubyVMFrozenCore; 休息; 案例 VM_SPECIAL_OBJECT_CBASE: val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); 休息; 默认: rb_bug("putspecialobject insn: 未知 value_type"); } }
在哪里:
VM_SPECIAL_OBJECT_VMCORE = 1 VM_SPECIAL_OBJECT_CBASE = 2
换句话说,如果参数为 1,rb_mRubyVMFrozenCore
则被压入堆栈,这是一个在 VM 启动早期创建的对象,它实现了一些语言特性作为方法:
set_method_alias(klass,:new,:old) 别名 new old set_variable_alias(:$new,:$old) 别名 $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”传递给上述方法的类。
所以
定义富 ... 结尾
编译为:
[:putspecialobject, 1], [:putspecialobject, 2], [:putobject, :foo], [:putiseq, [...]], [:send, :"core#define_method", 3, nil, 0, nil]
这就是我可以逆向工程的能力,这对这段代码来说并不容易。