Как работает код операции putpecialobject в RubyVM? - PullRequest
0 голосов
/ 22 мая 2009

Я работаю над реализацией RubyVM и искал всю документацию по кодам операций, но безрезультатно.

Если кто-то точно знает, как работает код операции putspecialobject, или даже просто ссылку на какую-то полную документацию, я был бы очень признателен!

1 Ответ

4 голосов
/ 30 августа 2009

Из 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]

Это столько, сколько я мог бы перепроектировать, что нелегко с этим кодом.

...