0

我正在研究 RubyVM 的实现,并且我到处搜索有关操作码的一些文档,但无济于事。

如果有人具体知道putspecialobject操作码是如何工作的,或者只是一个指向一些完整文档的链接,我将不胜感激!

4

1 回答 1

4

来自 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]

这就是我可以逆向工程的能力,这对这段代码来说并不容易。

于 2009-08-30T07:23:21.160 回答