Project

General

Profile

Bug #8484

Updated by nobu (Nobuyoshi Nakada) over 10 years ago


 r41041 で、ブロック呼び出し前の VM 内の処理中に Ruby のメソッドが何らかの理由で呼ばれると argv が壊れるという問題を直しました。 
 具体的には、 

 ~~~ruby 
 

     y = Object.new 
 
     def y.s(a) 
   
       yield(a) 
 
     end 
 
     m = Object.new 
 
     def m.method_missing(*a) 
   
       super 
 
     end 
 
     assert_equal [m, nil], y.s(m){|a,b|[a,b]} 
 ~~~ 

 のようなコードの場合、 
 * `y.s` y.s`m` m`block` block が渡される 
 * `y.s` y.s`yield(a)` yield(a) が呼ばれる 
 * `argv`が設定される argvが設定される 
 * `vm_invoke_block` vm_invoke_block 内の `VALUE VALUE * const rsp = GET_SP() - ci->argc; SET_SP(rsp);` SET_SP(rsp);`argv` argv の先頭に `sp` sp が設定される 
 * `vm_yield_setup_args` vm_yield_setup_args 
 * `vm_yield_setup_block_args` vm_yield_setup_block_args 
 * `y.s` のブロックパラメータは2つなのに、引数は一つなので、`a.to_ary` y.s のブロックパラメータは2つなのに、引数は一つなので、a.to_ary が呼ばれる (`rb_check_array_type(arg0)`) (rb_check_array_type(arg0)) 
 * `method_missing` method_missing が呼ばれる 
 * `super` super が呼ばれる (このへんで `vm _push_frame` vm _push_frame が呼ばれる) 
 * `vm_push_frame`のinitialize vm_push_frameのinitialize local variablesのところで`argv`に`nil`が代入されて破壊される variablesのところでargvにnilが代入されて破壊される 

 で、これ自体は `argv` argv を対比しておいて戻せばよいです。 
 また、`SET_SP(rsp)`のあたりは、ささださん曰く「 `argv` また、SET_SP(rsp)のあたりは、ささださん曰く「 argv に書き込みがない、という前提でそこは作ってるんだよね」だそうな。 
 しかし、「そんな前提わかるかっ」ですし、 
 methodの方は `SAVE_RESTORE_CI(tmp SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);` ci); ともうちょっとわかりやすく書いてあるので、 
 「頂いた問題点を元に、一度全部総点検が必要そうです」とのことですので、お願いします。 

Back