未来のいつか/hyoshiokの日記

hyoshiokの日々思うことをあれやこれや

RHGの逆襲

自分用のメモ。YARVの実装の話

topにあるのとincludeの下の.hの差は?

topにあるのは、外から使わせない。includeは使われることがある。

rb_vm_tってどこですか?最新版だとrb_vm_tが定義されている。
rb_vm_struct。

svn updateして自分のソースを最新版にする。

YARVはスタックマシンだ。
命令iseqでさしている

$ ./ruby --dump=insn -e '1..3'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
0000 trace            1                                               (   1)
0002 putobject        1..3
0004 leave            
$ ./ruby --dump=insn -e '1..n'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
0000 trace            1                                               (   1)
0002 putobject        1
0004 putnil           
0005 send             :n, 0, nil, 24, <ic>
0011 newrange         0
0013 leave            
$ ./ruby --dump=insn -e 'n=3; 1..n'
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] n          
0000 trace            1                                               (   1)
0002 putobject        3
0004 setlocal         n
0006 trace            1
0008 putobject        1
0010 getlocal         n
0012 newrange         0
0014 leave            

vm.incを読む

INSN_ENTRY(newrange){
{
  VALUE val;
  rb_num_t flag = (rb_num_t)GET_OPERAND(1);
  VALUE low = TOPN(1);
  VALUE high = TOPN(0);
  DEBUG_ENTER_INSN("newrange");
  ADD_PC(1+1);
  PREFETCH(GET_PC());
  POPN(2);
  #define CURRENT_INSN_newrange 1
  #define INSN_IS_SC()     0
  #define INSN_LABEL(lab)  LABEL_newrange_##lab
  #define LABEL_IS_SC(lab) LABEL_##lab##_##t
  USAGE_ANALYSIS_INSN(BIN(newrange));
  USAGE_ANALYSIS_OPERAND(BIN(newrange), 0, flag);
{
#line 608 "insns.def"
    val = rb_range_new(low, high, flag);

#line 905 "vm.inc"
  PUSH(val);
#undef CURRENT_INSN_newrange
#undef INSN_IS_SC
#undef INSN_LABEL
#undef LABEL_IS_SC
  END_INSN(newrange);}}}

answerの実装。
SUPPORT_JOKEを定義すればいい

だめだ。というのは、id.hがvm_opts.hを#includeしていない。

$ svn diff id.h
Index: id.h
===================================================================
--- id.h	(revision 20086)
+++ id.h	(working copy)
@@ -27,6 +27,7 @@
 #ifdef USE_PARSE_H
 #include "parse.h"
 #endif
+#include "vm_opts.h"
 
 #define symIFUNC ID2SYM(idIFUNC)
 #define symCFUNC ID2SYM(idCFUNC)

ということで、ruby 1.9 初パッチ

$ ./ruby --dump=insn -e 'p the_answer_to_life_the_universe_and_everything' 
== disasm: <RubyVM::InstructionSequence:<main>@-e>======================
0000 trace            1                                               (   1)
0002 putnil           
0003 answer           
0004 send             :p, 1, nil, 8, <ic>
0010 leave            
$ ./ruby -e 'p the_answer_to_life_the_universe_and_everything'
42